我有以下类别描述代码段:
... @Column(name = "invalidate_token_date") @Temporal(TemporalType.TIMESTAMP) private LocalDateTime invalidateTokenDate; ....
该代码在Hibernate 4上不起作用,因为@Temporal不支持LocalDateTime.
@Temporal
LocalDateTime.
我从 Joda-Time 看到了有关如何使用 LocalDateTime 的建议,但我使用的是Java 8。 __
由于Hibernate 4不支持它,因此您需要实现一个如本示例所示的用户类型。
import org.hibernate.HibernateException; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.type.StandardBasicTypes; import org.hibernate.usertype.EnhancedUserType; 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; public class LocalDateTimeUserType implements EnhancedUserType, Serializable { 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); } }
然后,可以在带有@Type批注的映射中使用新的用户类型。例如
@Type(type="com.hibernate.samples.type.LocalDateTimeUserType") @Column(name = "invalidate_token_date") private LocalDateTime invalidateTokenDate;
@Type批注需要一个实现userType接口的类的完整路径;这是用于生成映射列的目标类型的工厂。
这是在JPA2.1中执行相同操作的方法