我的实体中有Calendar
字段
@Column(nullable = false)
private Calendar transmissionDate;
需要毫秒精度。就像,Hibernate生成一个模式,将该字段映射到
+-------------------+--------------+------+-----+---------+
| Field | Type | Null | Key | Default |
+-------------------+--------------+------+-----+---------+
| transmission_date | datetime | NO | | NULL |
+-------------------+--------------+------+-----+---------+
在MySQL中。 The datetime
type in MySQL discards everything after the second,所以我失去了精确度。我一直在使用的解决方案是
@Column(nullable = false)
private Long transmissionDate;
并在需要时从中生成Calendar实例。
这是一个巨大的麻烦,我想知道Hibernate是否具有可以克服它的功能。 This question显示了如何使用自定义类型,但是,实现它,Hibernate仍然映射到datetime
列类型。
如何在我的实体中仍使用Calendar
类型时保持毫秒精度?
答案 0 :(得分:1)
我使用将UserType
映射到Calendar
的自定义BIGINT
让它工作。
public class CalendarType implements UserType {
@Override
public int[] sqlTypes() {
return new int[] {Types.BIGINT};
}
@Override
public Class<?> returnedClass() {
return Calendar.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return x.equals(y);
}
@Override
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
@Override
public Object nullSafeGet(ResultSet resultSet, String[] names,SessionImplementor session, Object owner) throws HibernateException, SQLException {
Long timeInMillis = resultSet.getLong(names[0]);
if (timeInMillis == null) {
return null;
} else {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeInMillis);
return calendar;
}
}
@Override
public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
Calendar calendar = (Calendar) value;
preparedStatement.setLong(index, calendar.getTimeInMillis());
}
@Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
Calendar calendar = (Calendar) value;
return calendar.getTimeInMillis();
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
Long timeInMillis = (Long) cached;
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeInMillis);
return calendar;
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
}
然后我的实体
@TypeDef(name = "calendarType", typeClass = CalendarType.class)
@Entity
@Table
public class Entity {
@Type(type = "calendarType")
@Column(nullable = false)
private Calendar transmissionDate;
...
}
Hibernate是该死的神奇。
答案 1 :(得分:0)
使用Joda DateTime。您可以map it directly in Hibernate使用org.joda.time.contrib.hibernate.PersistentDateTime
类,它具有毫秒精度。
@Column
@Type(type="org.joda.time.contrib.hibernate.PersistentDateTime")
private DateTime transmissionDate;