Hibernate – 将java.util.Calendar映射到MySQL BIGINT

我的实体中有一个Calendar字段

 @Column(nullable = false) private Calendar transmissionDate; 

这需要毫秒精度。 就像,Hibernate生成一个模式,将该字段映射到

 +-------------------+--------------+------+-----+---------+ | Field | Type | Null | Key | Default | +-------------------+--------------+------+-----+---------+ | transmission_date | datetime | NO | | NULL | +-------------------+--------------+------+-----+---------+ 

在MySQL中。 MySQL中的datetime类型在第二个之后丢弃所有内容 ,因此我失去了精度。 我一直在使用的解决方案是

 @Column(nullable = false) private Long transmissionDate; 

并在需要时从中生成Calendar实例。

这是一个巨大的麻烦,我想知道Hibernate是否具有可以克服它的function。 这个问题展示了如何使用自定义类型,但是,实现它,Hibernate仍然映射到datetime列类型。

如何在我的实体中仍然使用Calendar类型时保持毫秒精度?

我使用自定义UserTypeCalendar映射到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是神该死的神奇。

使用Joda DateTime 。 您可以使用org.joda.time.contrib.hibernate.PersistentDateTime类直接在Hibernate中映射它,并且它具有毫秒精度。

 @Column @Type(type="org.joda.time.contrib.hibernate.PersistentDateTime") private DateTime transmissionDate;