如何在JPA和Hibernate中使用Java 8 LocalDateTime

我有以下类别描述代码段:

... 

@Column(name = "invalidate_token_date")

@Temporal(TemporalType.TIMESTAMP)

private LocalDateTime invalidateTokenDate;

....

该代码在Hibernate 4上不起作用,因为@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中执行相同操作的方法

以上是 如何在JPA和Hibernate中使用Java 8 LocalDateTime 的全部内容, 来源链接: utcz.com/qa/426180.html

回到顶部