您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

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

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

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

        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相关联

        Iterator clsMappings = cfg.getClassMappings();
    while(clsMappings.hasNext()){
        PersistentClass mapping = (PersistentClass) clsMappings.next();
        handleProperties(mapping.getPropertyIterator(), map);
    }
        Type result = TypeFactory.heuristicType(typeName, typeParameters);

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

     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);
            }
        }
    }
        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;
        }
        ...
    }
        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)。

java 2022/1/1 18:17:39 有496人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶