Yuriy
Yuriy

Reputation: 1442

java.io.StreamCorruptedException: invalid stream header: 41434544

I attempt to serealize and to deserialize LocalDateTime via jackson. I use hibernate + restful webservices. It is my entity:

@Entity
@Table(name = "USERS")
@NamedQueries(value = { 
    @NamedQuery(name = "getUser", query = "from User user where userId = ?") 
})
public class User extends ResourceSupport implements Serializable{

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "USER_ID")
private long userId;

@Column(name = "USER_NAME")
private String userName;

@Column(name = "USER_CREATED")

@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)

private LocalDateTime userCreated;

@Column(name = "USER_PHONE")
private String userPhone;


public User(){}

@JsonCreator
public User(@JsonProperty("userId") long userId,
            @JsonProperty("userName") String userName, 
            @JsonProperty("phone") String phone) {
    super();
    this.userId = userId;
    this.userName = userName;
    this.userPhone = phone;
    this.userCreated = LocalDateTime.now();
}
public long getUserId() {
    return userId;
}
public void setUserId(long userId) {
    this.userId = userId;
}
public String getUserName() {
    return userName;
}
public void setUserName(String userName) {
    this.userName = userName;
}

public LocalDateTime getUserCreated() {
    return userCreated;
}

public void setUserCreated(LocalDateTime userCreated) {
    this.userCreated = userCreated;
}

public String getUserPhone() {
    return userPhone;
}

public void setUserPhone(String userPhone) {
    this.userPhone = userPhone;
}

@Override
public boolean equals(Object user){
    boolean result = false;
    if((user==null)||!(user instanceof User))
        result = false;
    else{
        User otherUser = (User)user;
        result = this.getUserId() == otherUser.getUserId() &&
                 this.getUserName() == otherUser.getUserName() &&
                 this.getUserPhone() == otherUser.getUserPhone()&&
                 this.getUserCreated() == otherUser.getUserCreated();
    }
    return result;
}

@Override
public int hashCode(){
    return Long.hashCode(userId) ;
}

It is my serializer:

public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime>{

    @Override
    public void serialize(LocalDateTime arg0, JsonGenerator arg1, SerializerProvider arg2)
            throws IOException, JsonProcessingException {
        // TODO Auto-generated method stub
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedDateTime = arg0.format(formatter);
        arg1.writeString(formattedDateTime);
    }

}

It is my deserializer:

public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {

    @Override
    public LocalDateTime deserialize(JsonParser arg0, DeserializationContext arg1)
            throws IOException, JsonProcessingException {
        // TODO Auto-generated method stub
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime localDateTime = LocalDateTime.parse(arg0.getText(), formatter);
        return localDateTime;
    }

}

It is my DAO class:

@Repository
public class UserDAOImpl implements UserDAO{

@Autowired
private SessionFactory sessionFactory;

public UserDAOImpl(){}
public UserDAOImpl(SessionFactory sessionFactory){
    this.sessionFactory = sessionFactory;
}


@Override
public User getUser(long userId) {
    //Session session = sessionFactory.getCurrentSession();
    Session session = sessionFactory.openSession();
    Query query = session.getNamedQuery("getUser");
    query.setParameter(0, userId);

    return (User)query.uniqueResult();// this string invokes error
}
@Override
public void addUser(User user) {
    // TODO Auto-generated method stub
    Session session = sessionFactory.openSession();
    user.setUserCreated(LocalDateTime.now());
    session.save(user);
    session.flush();
    session.close();
}

It is value of USER_CREATED field of my saved user:

  ACED00057372000D6A6176612E74696D652E536572955D84BA1B2248B20C00007870770E05000007E004110F261012C684C078

When I add user to db, adding operation is executing succesfully, but when I attempt get user from DB I get error:

java.io.StreamCorruptedException: invalid stream header: 41434544
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:806) ~[na:1.8.0_73]
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299) ~[na:1.8.0_73]
at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:309) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:299) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:218) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.internal.util.SerializationHelper.deserialize(SerializationHelper.java:287) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.fromBytes(SerializableTypeDescriptor.java:138) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:113) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:27) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$2.doExtract(VarbinaryTypeDescriptor.java:53) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:238) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:234) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:224) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:300) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2727) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1728) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1654) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.getRow(Loader.java:1543) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:727) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.processResultSet(Loader.java:972) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.doQuery(Loader.java:930) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2611) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2594) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2423) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.list(Loader.java:2418) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:501) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:371) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1326) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:87) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.internal.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:960) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.company.dao.UserDAOImpl.getUser(UserDAOImpl.java:30) ~[classes/:na]
at org.company.dao.UserDAOImpl$$FastClassBySpringCGLIB$$d4b6a590.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720) ~[spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) ~[spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.company.dao.UserDAOImpl$$EnhancerBySpringCGLIB$$21463096.getUser(<generated>) ~[classes/:na]
at org.company.service.UserServiceImpl.getUser(UserServiceImpl.java:39) ~[classes/:na]
at org.company.controller.UserController.getUser(UserController.java:43) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_73]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_73]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_73]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_73]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.32.jar:8.0.32]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_73]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_73]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.32.jar:8.0.32]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_73]

Upvotes: 0

Views: 7042

Answers (2)

Stephen C
Stephen C

Reputation: 718886

I have an idea what is going on here. Here are the clues.

So it looks like you have done the following:

  1. You have serialized some object into a byte array.
  2. You have converted the byte array to text comprising a hexadecimal representation of the bytes.
  3. You have saved that text in a VARCHAR (or similar) column of some table.
  4. You have then retrieved the text.
  5. You have used String.getBytes(...) to convert the text to bytes.
  6. You have tried to deserialize the bytes.

The problem is that step 5 is wrong. You need to convert the text to bytes by splitting the string into pairs of characters (hex digits) and converting each pair to a byte.


UPDATE - apparently, Hibernate is doing the serialization behind the scenes, and the correct solution is to stop it happening; see @JB Nizet's answer.

Upvotes: 4

JB Nizet
JB Nizet

Reputation: 691755

Hibernate doesn't support LocalDateTime, unless you add an additional jar to your classpath.

That means that without it, it treats LocalDateTime as any serializable class, and uses native Java serialization to store the value into a binary column of the table. You really, really don't want that.

Also, don't compare objects with ==. And note that this has nothing to do with JSON and Jackson.

Upvotes: 3

Related Questions