hibernate java.util.date 精度_如何强制Hibernate将日期返回为java.util.Date而不是Timestamp?...

小编典典

因此,我花了一些时间解决这个问题,并找到了解决方案。它不是一个漂亮的东西,但至少是一个起点-也许有人会用一些有用的注释来补充它。

我在处理中发现的一些有关映射的信息:

包含Hibernate类型到属性类型的基本映射的类是org.hibernate.type.TypeFactory。所有这些映射都存储在不可修改的映射中

private static final Map BASIC_TYPES;

...

basics.put( java.util.Date.class.getName(), Hibernate.TIMESTAMP );

...

BASIC_TYPES = Collections.unmodifiableMap( basics );

如您所见,java.util.Date类型与Hibernate类型org.hibernate.type.TimestampType相关联

下一个有趣的时刻-创建Hibernate org.hibernate.cfg.Configuration-包含有关映射类的所有信息的对象。此类及其属性可以像这样提取:

Iterator clsMappings = cfg.getClassMappings();

while(clsMappings.hasNext()){

PersistentClass mapping = (PersistentClass) clsMappings.next();

handleProperties(mapping.getPropertyIterator(), map);

}

绝大多数属性是org.hibernate.mapping.SimpleValue类型的对象。我们的兴趣点是方法SimpleValue.getType()-在此方法中定义了在处理DB时将使用哪种类型来回转换属性值

Type result = TypeFactory.heuristicType(typeName, typeParameters);

至此,我了解到我无法修改BASIC_TYPES(这是唯一的方法),无法将SimpleValue对象替换为java.util.Date类型的属性,更改为我的自定义对象,从而可以知道要转换的确切类型。

解决方案:

通过扩展HibernatePersistence类并覆盖其方法createContainerEntityManagerFactory来创建自定义容器实体管理器工厂:

public class HibernatePersistenceExtensions extends HibernatePersistence {

@Override

public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map) {

if ("true".equals(map.get("hibernate.use.custom.entity.manager.factory"))) {

return CustomeEntityManagerFactoryFactory.createCustomEntityManagerFactory(info, map);

} else {

return super.createContainerEntityManagerFactory(info, map);

}

}

}

创建Hibernate配置对象,修改java.util.Date属性的值对象,然后创建自定义实体管理器工厂。

public class ReattachingEntityManagerFactoryFactory {

@SuppressWarnings("rawtypes")

public static EntityManagerFactory createContainerEntityManagerFactory(

PersistenceUnitInfo info, Map map) {

Ejb3Configuration cfg = new Ejb3Configuration();

Ejb3Configuration configured = cfg.configure( info, map );

handleClassMappings(cfg, map);

return configured != null ? configured.buildEntityManagerFactory() : null;

}

@SuppressWarnings("rawtypes")

private static void handleClassMappings(Ejb3Configuration cfg, Map map) {

Iterator clsMappings = cfg.getClassMappings();

while(clsMappings.hasNext()){

PersistentClass mapping = (PersistentClass) clsMappings.next();

handleProperties(mapping.getPropertyIterator(), map);

}

}

private static void handleProperties(Iterator props, Map map) {

while(props.hasNext()){

Property prop = (Property) props.next();

Value value = prop.getValue();

if (value instanceof Component) {

Component c = (Component) value;

handleProperties(c.getPropertyIterator(), map);

} else {

handleReturnUtilDateInsteadOfTimestamp(prop, map);

}

}

private static void handleReturnUtilDateInsteadOfTimestamp(Property prop, Map map) {

if ("true".equals(map.get("hibernate.return.date.instead.of.timestamp"))) {

Value value = prop.getValue();

if (value instanceof SimpleValue) {

SimpleValue simpleValue = (SimpleValue) value;

String typeName = simpleValue.getTypeName();

if ("java.util.Date".equals(typeName)) {

UtilDateSimpleValue udsv = new UtilDateSimpleValue(simpleValue);

prop.setValue(udsv);

}

}

}

}

}

如您所见,我只是遍历每个属性,并用SimpleValue-object替换UtilDateSimpleValue来替换类型java.util.Date的属性。这是一个非常简单的类-它实现与SimpleValue对象相同的接口,例如org.hibernate.mapping.KeyValue。在构造函数中,将传递原始SimpleValue对象-

因此,每次调用UtilDateSimpleValue都会被重定向到原始对象,但有一个异常-方法getType(…)返回我的自定义类型。

public class UtilDateSimpleValue implements KeyValue{

private SimpleValue value;

public UtilDateSimpleValue(SimpleValue value) {

this.value = value;

}

public SimpleValue getValue() {

return value;

}

@Override

public int getColumnSpan() {

return value.getColumnSpan();

}

...

@Override

public Type getType() throws MappingException {

final String typeName = value.getTypeName();

if (typeName == null) {

throw new MappingException("No type name");

}

Type result = new UtilDateUserType();

return result;

}

...

}

最后一步是UtilDateUserType的实现。我只是扩展了原始的org.hibernate.type.TimestampType并覆盖了它的方法get(),如下所示:

public class UtilDateUserType extends TimestampType{

@Override

public Object get(ResultSet rs, String name) throws SQLException {

Timestamp ts = rs.getTimestamp(name);

Date result = null;

if(ts != null){

result = new Date(ts.getTime());

}

return result;

}

}

就这些。有点棘手,但是现在每个java.util.Date属性都作为java.util.Date返回,而无需对现有代码进行任何其他修改(注释或修改setter)。

2020-06-20

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值