jdk1.8 日期新API LocalDateTime,LocalDate,LocalTime 在Hibernate中无法反序列化解决方法

来源:互联网 发布:如何进入服务器数据库 编辑:程序博客网 时间:2024/05/14 20:36

java JDK1.8 引入全新的时间日期API但是无法结合Hibernate使用,hibernate源码并未对其进行支持,所以要使用hibernate的扩展进行支持。

以下是演示LocalDateTime如何使用,其余两个(LocalDateLocalTime)的做法是一样的。



解决错误如下:

Caused by: org.hibernate.type.SerializationException: could not deserializeat org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:263)at org.hibernate.internal.util.SerializationHelper.deserialize(SerializationHelper.java:307)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:2562)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:2552)at org.hibernate.loader.Loader.doList(Loader.java:2538)at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2368)at org.hibernate.loader.Loader.list(Loader.java:2363)at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:126)at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1724)at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:380)at oa.dao.CrudRepositoryImpl.findByCriteria(CrudRepositoryImpl.java:212)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:483)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.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)... 66 more</span>


解决方法如下:


创建一个类对其进行支持

import java.io.Serializable;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Types;import java.time.Instant;import java.time.LocalDateTime;import java.time.ZoneId;import java.util.Date;import org.hibernate.HibernateException;import org.hibernate.engine.spi.SessionImplementor;import org.hibernate.type.StandardBasicTypes;import org.hibernate.usertype.EnhancedUserType; public class LocalDateTimeType implements EnhancedUserType, Serializable {private static final long serialVersionUID = 2208831017183219350L;private static final int[] SQL_TYPES = new int[]{Types.TIMESTAMP};//指定在数据库中的类型     @Override    public int[] sqlTypes() {        return SQL_TYPES;    }     @Override    public Class<?> returnedClass() {        return LocalDateTime.class;//指定要反序列化的自定义类型    }     @Override    public boolean equals(Object x, Object y) throws HibernateException {        if (x == y) {            return true;        }        if (x == null || y == null) {            return false;        }        LocalDateTime dtx = (LocalDateTime) x;        LocalDateTime dty = (LocalDateTime) y;        return dtx.equals(dty);    }     @Override    public int hashCode(Object object) throws HibernateException {        return object.hashCode();    }      @Override    public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor session, Object owner)            throws HibernateException, SQLException {        Object timestamp = StandardBasicTypes.TIMESTAMP.nullSafeGet(resultSet, names, 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 preparedStatement, Object value, int index, SessionImplementor session)            throws HibernateException, SQLException {        if (value == null) {            StandardBasicTypes.TIMESTAMP.nullSafeSet(preparedStatement, null, index, session);        } else {            LocalDateTime ldt = ((LocalDateTime) value);            Instant instant = ldt.atZone(ZoneId.systemDefault()).toInstant();            Date timestamp = Date.from(instant);            StandardBasicTypes.TIMESTAMP.nullSafeSet(preparedStatement, timestamp, index, session);        }    }     @Override    public Object deepCopy(Object value) throws HibernateException {        return value;    }     @Override    public boolean isMutable() {        return false;    }     @Override    public Serializable disassemble(Object value) throws HibernateException {        return (Serializable) value;    }     @Override    public Object assemble(Serializable cached, Object value) throws HibernateException {        return cached;    }     @Override    public Object replace(Object original, Object target, Object owner) throws HibernateException {        return original;    }     @Override    public String objectToSQLString(Object object) {        throw new UnsupportedOperationException();    }     @Override    public String toXMLString(Object object) {        return object.toString();    }     @Override    public Object fromXMLString(String string) {        return LocalDateTime.parse(string);    } }




在hibernate中的映射文件引用如下

<property name="属性名称" type="oa.common.type.LocalDateTimeType">        <column name="属性名称" sql-type="timestamp">                <comment>注释内容</comment>        </column></property>


在hibernate注解类添加如下注解

@TypeDefs({@TypeDef(name = "localDateTimeType",defaultForType = LocalDateTime.class,typeClass = LocalDateTimeType.class)})


0 0
原创粉丝点击