1

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;

并在需要时从中生成一个日历实例。

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

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

4

2 回答 2

1

I got it to work using a custom UserType that maps a Calendar to a 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;
    }
}

And my Entity then has

@TypeDef(name = "calendarType", typeClass = CalendarType.class)
@Entity
@Table
public class Entity {

    @Type(type = "calendarType")
    @Column(nullable = false)
    private Calendar transmissionDate;

    ...
}

Hibernate is god damn magical.

于 2013-07-17T19:12:06.643 回答
0

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

@Column
@Type(type="org.joda.time.contrib.hibernate.PersistentDateTime")
private DateTime transmissionDate;
于 2013-07-17T15:56:38.313 回答