org hibernate type SerializationException could not deserialize

org hibernate type SerializationException could not deserialize

This is very common exception if you are working with hibernate. This happens while you make call to the database where connection to the database is successful but while returning the data java model class for hibernate not able to deserialize and map the data. It occurs due to data mismatch and most of time I saw it happens for date attribute. Below is full details of exception:

Exception in thread “main” org.hibernate.type.SerializationException: could not deserialize

Caused by: java.io.StreamCorruptedException: invalid stream header: 0000A540

Exception in thread "main" org.hibernate.type.SerializationException: could not deserialize
	at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:262)
	at org.hibernate.internal.util.SerializationHelper.deserialize(SerializationHelper.java:306)
	at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.fromBytes(SerializableTypeDescriptor.java:155)
	at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:130)
	at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:44)
	at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$2.doExtract(VarbinaryTypeDescriptor.java:70)
	at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:64)
	at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:267)
	at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:263)
	at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:253)
	at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:338)
	at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2969)
	at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1696)
	at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1628)
	at org.hibernate.loader.Loader.getRow(Loader.java:1515)
	at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:726)
	at org.hibernate.loader.Loader.processResultSet(Loader.java:953)
	at org.hibernate.loader.Loader.doQuery(Loader.java:921)
	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355)
	at org.hibernate.loader.Loader.doList(Loader.java:2554)
	at org.hibernate.loader.Loader.doList(Loader.java:2540)
	at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370)
	at org.hibernate.loader.Loader.list(Loader.java:2365)
	at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:497)
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:387)
	at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:236)
	at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1300)
	at org.hibernate.internal.QueryImpl.list(QueryImpl.java:103)
	at com.javahonk.dao.InterestRateDaoHandler.getInterestRates(InterestRateDaoHandler.java:34)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
	at com.sun.proxy.$Proxy33.getInterestRates(Unknown Source)
	at com.javahonk.SpringHibernateMultipleTestApp.main(SpringHibernateMultipleTestApp.java:42)
Caused by: java.io.StreamCorruptedException: invalid stream header: 0000A540
	at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
	at java.io.ObjectInputStream.<init>(Unknown Source)
	at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:328)
	at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:318)
	at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:237)
	... 42 more
  • Solution: You will have to properly deserialize the data in your model class. Below is two class which you can use one for LocalDate and another one for LocalDateTime:

LocalDateHibernateUserType.java:

package com.javahonk.model;

import java.io.Serializable;
import java.util.Date;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.usertype.EnhancedUserType;

public class LocalDateHibernateUserType implements EnhancedUserType, Serializable{

	private static final long serialVersionUID = -7500395414633111738L;
	private static final int[] sql_types = new int[]{Types.TIMESTAMP};

	@Override
	public Object assemble(Serializable arg0, Object arg1)
			throws HibernateException {
		return arg0;
	}

	@Override
	public Object deepCopy(Object arg0) throws HibernateException {
		return arg0;
	}

	@Override
	public Serializable disassemble(Object arg0) throws HibernateException {
		return (Serializable) arg0;
	}

	@Override
	public boolean equals(Object obj1, Object obj2) throws HibernateException {
		if(obj1 == obj2)
			return true;
		
		if(obj1==null || obj2 == null)
			return false;
		
		LocalDate ldt1 = (LocalDate)obj1;
		LocalDate ldt2 = (LocalDate)obj2;
		
		return ldt1.equals(ldt2);
	}

	@Override
	public int hashCode(Object arg0) throws HibernateException {
		return arg0.hashCode();
	}

	@Override
	public boolean isMutable() {
		return false;
	}

	@Override
	public Object nullSafeGet(ResultSet rs, String[] params,
			SessionImplementor session, Object owner) throws HibernateException,
			SQLException {
		
		Object timestamp = StandardBasicTypes.DATE.nullSafeGet(rs, params, session, owner);
		
		if(timestamp == null){
			return null;
		}
		
		Date date = (Date) timestamp;
		Instant instant = Instant.ofEpochMilli(date.getTime());
		
		return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).toLocalDate();
	}

	@Override
	public void nullSafeSet(PreparedStatement ps, Object value, int index,
			SessionImplementor session) throws HibernateException, SQLException {
		if(value==null){
			StandardBasicTypes.DATE.nullSafeSet(ps, null, index, session);
		}
		else{
			LocalDate ldt = (LocalDate) value;
			Instant instant = ldt.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
			Date date = Date.from(instant);
			StandardBasicTypes.DATE.nullSafeSet(ps, date, index, session);
		}
		
	}

	@Override
	public Object replace(Object original, Object target, Object owner)
			throws HibernateException {
		return original;
	}

	@SuppressWarnings("rawtypes")
	@Override
	public Class returnedClass() {
		return LocalDate.class;
	}

	@Override
	public int[] sqlTypes() {
		return sql_types;
	}

	@Override
	public Object fromXMLString(String arg0) {
		return LocalDate.parse(arg0);
	}

	@Override
	public String objectToSQLString(Object arg0) {
		throw new UnsupportedOperationException();
	}

	@Override
	public String toXMLString(Object arg0) {
		return arg0.toString();
	}

}
  • LocalDateTimeHibernateUserType.java:
package com.javahonk.model;

import java.io.Serializable;
import java.util.Date;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.usertype.EnhancedUserType;

public class LocalDateTimeHibernateUserType implements EnhancedUserType, Serializable{

	private static final long serialVersionUID = 2769071855811042550L;
	private static final int[] sql_types = new int[]{Types.TIMESTAMP};

	@Override
	public Object assemble(Serializable arg0, Object arg1)
			throws HibernateException {
		return arg0;
	}

	@Override
	public Object deepCopy(Object arg0) throws HibernateException {
		return arg0;
	}

	@Override
	public Serializable disassemble(Object arg0) throws HibernateException {
		return (Serializable) arg0;
	}

	@Override
	public boolean equals(Object obj1, Object obj2) throws HibernateException {
		if(obj1 == obj2)
			return true;
		
		if(obj1==null || obj2 == null)
			return false;
		
		LocalDateTime ldt1 = (LocalDateTime)obj1;
		LocalDateTime ldt2 = (LocalDateTime)obj2;
		
		return ldt1.equals(ldt2);
	}

	@Override
	public int hashCode(Object arg0) throws HibernateException {
		return arg0.hashCode();
	}

	@Override
	public boolean isMutable() {
		return false;
	}

	@Override
	public Object nullSafeGet(ResultSet rs, String[] params,
			SessionImplementor session, Object owner) throws HibernateException,
			SQLException {
		
		Object timestamp = StandardBasicTypes.TIMESTAMP.nullSafeGet(rs, params, session, owner);
		
		if(timestamp == null){
			return null;
		}
		
		Date ts = (Date) timestamp;
		Instant instant = Instant.ofEpochMilli(ts.getTime());
		
		return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
	}

	@Override
	public void nullSafeSet(PreparedStatement ps, Object value, int index,
			SessionImplementor session) throws HibernateException, SQLException {
		if(value==null){
			StandardBasicTypes.TIMESTAMP.nullSafeSet(ps, null, index, session);
		}
		else{
			LocalDateTime ldt = (LocalDateTime) value;
			Instant instant = ldt.atZone(ZoneId.systemDefault()).toInstant();
			Date timestamp = Date.from(instant);
			StandardBasicTypes.TIMESTAMP.nullSafeSet(ps, timestamp, index, session);
		}
		
	}

	@Override
	public Object replace(Object original, Object target, Object owner)
			throws HibernateException {
		return original;
	}

	@SuppressWarnings("rawtypes")
	@Override
	public Class returnedClass() {
		return LocalDateTime.class;
	}

	@Override
	public int[] sqlTypes() {
		return sql_types;
	}

	@Override
	public Object fromXMLString(String arg0) {
		return LocalDateTime.parse(arg0);
	}

	@Override
	public String objectToSQLString(Object arg0) {
		throw new UnsupportedOperationException();
	}

	@Override
	public String toXMLString(Object arg0) {
		return arg0.toString();
	}

}

Very important:

  • Suppose you hibernate query is returning LocalDate and if attributes defined in model then you can use as below:
@Column(name="extracting_date")
@Type(type = "com.javahonk.model.LocalDateHibernateUserType")
private LocalDate extracting_date;
  • If you are using LocalDateTime then please include in your model class as below:
@Column(name="extracting_date")
@Type(type = "com.javahonk.model.LocalDateTimeHibernateUserType")
private LocalDateTime extracting_date;

This should resolve above issue. For more information please visit here

One thought on “org hibernate type SerializationException could not deserialize”

Leave a Reply

Your email address will not be published. Required fields are marked *