Hibernate - 将java.util.Calendar映射到MySQL BIGINT [英] Hibernate - Mapping java.util.Calendar to MySQL BIGINT
问题描述
我的实体中有一个日历
字段
@Column (nullable = false)
私人日历transmissionDate;
这需要毫秒精度。就像这样,Hibernate生成一个模式,将这个字段映射到一个
+ ------------ ------- + -------------- + ------ + ----- + --------- +
|字段|类型|空| Key |默认|
+ ------------------- + -------------- + ------ + --- - + --------- +
| transmission_date | datetime | NO | | NULL |
+ ------------------- + -------------- + ------ + --- - + --------- +
在MySQL中。 datetime
类型在MySQL中丢弃了所有内容,所以我失去了精确度。我现在使用的解决方案是:
@Column(nullable = false)
private Long transmissionDate;
并根据需要生成一个Calendar实例。
这是一个巨大的麻烦,我想知道Hibernate是否具有可以克服它的功能。 这个问题显示你可以如何使用自定义类型,但实现它,Hibernate仍然映射到 datetime
列类型。
如何能在我的实体中仍然使用 Calendar
类型时,我保留了毫秒级的精度?解析方案
我使用将的自定义
。 UserType
BIGINT
public class CalendarType implements UserType {
@Override
public int [] sqlTypes(){
return new int [] {Types.BIGINT};
}
@Override
public Class<?> returnedClass(){
return Calendar.class;
$ b @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();
$ b @Override
public Object nullSafeGet(ResultSet resultSet,String [] names,SessionImplementor session,Object owner)throws HibernateException,SQLException {
Long timeInMillis = resultSet .getLong(名称[0]);
if(timeInMillis == null){
return null;
} else {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeInMillis);
返回日历;
$ b @Override
public void nullSafeSet(PreparedStatement preparedStatement,Object value,int index,SessionImplementor session)throws HibernateException,SQLException {
Calendar日历=(日历)值;
preparedStatement.setLong(index,calendar.getTimeInMillis());
}
@Override
public Object deepCopy(Object value)throws HibernateException {
返回值;
}
@Override
public boolean isMutable(){
return false;
$ b @Override
public Serializable反汇编(Object value)抛出HibernateException {
Calendar calendar =(Calendar)value;
返回calendar.getTimeInMillis();
$ b @Override
public Object assemble(Serializable cached,Object owner)throws HibernateException {
Long timeInMillis =(Long)cached;
日历日历= Calendar.getInstance();
calendar.setTimeInMillis(timeInMillis);
返回日历;
}
@Override
public Object replace(Object original,Object target,Object owner)throws HibernateException {
return original;
然后我的实体拥有
@TypeDef(name =calendarType,typeClass = CalendarType.class)
@Entity
@Table
public类实体{
@Type(type =calendarType)
@Column(nullable = false)
private日历transmissionDate;
...
}
Hibernate真是神奇的魔法。
I have a Calendar
field in my entity
@Column(nullable = false)
private Calendar transmissionDate;
which needs millisecond precision. As is, Hibernate generates a schema, mapping this field to a
+-------------------+--------------+------+-----+---------+
| Field | Type | Null | Key | Default |
+-------------------+--------------+------+-----+---------+
| transmission_date | datetime | NO | | NULL |
+-------------------+--------------+------+-----+---------+
in MySQL. The datetime
type in MySQL discards everything after the second, so I lose my precision. The solution I've been using for now is
@Column(nullable = false)
private Long transmissionDate;
and generate a Calendar instance from it when it's required.
This is a huge hassle and I want to know if Hibernate has functionality that can overcome it. This question shows how you can use a custom type, but, implementing it, Hibernate is still mapping to a datetime
column type.
How can I retain the millisecond precision while still using the Calendar
type in my entity?
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.
这篇关于Hibernate - 将java.util.Calendar映射到MySQL BIGINT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!