How to force Hibernate to return dates as java.util.Date instead of Timestamp?

前端 未结 7 896
天涯浪人
天涯浪人 2020-12-04 08:13

Situation:

I have a persistable class with variable of java.util.Date type:

import java.util.Date;

@Entity
@Table(name = \"prd_peri         


        
7条回答
  •  一生所求
    2020-12-04 08:47

    Here is solution for Hibernate 4.3.7.Final.

    pacakge-info.java contains

    @TypeDefs(
        {
            @TypeDef(
                    name = "javaUtilDateType",
                    defaultForType = java.util.Date.class,
                    typeClass = JavaUtilDateType.class
            )
        })
    package some.pack;
    import org.hibernate.annotations.TypeDef;
    import org.hibernate.annotations.TypeDefs;
    

    And JavaUtilDateType:

    package some.other.or.same.pack;
    
    import java.sql.Timestamp;
    import java.util.Comparator;
    import java.util.Date;
    import org.hibernate.HibernateException;
    import org.hibernate.dialect.Dialect;
    import org.hibernate.engine.spi.SessionImplementor;
    import org.hibernate.type.AbstractSingleColumnStandardBasicType;
    import org.hibernate.type.LiteralType;
    import org.hibernate.type.StringType;
    import org.hibernate.type.TimestampType;
    import org.hibernate.type.VersionType;
    import org.hibernate.type.descriptor.WrapperOptions;
    import org.hibernate.type.descriptor.java.JdbcTimestampTypeDescriptor;
    import org.hibernate.type.descriptor.sql.TimestampTypeDescriptor;
    
    /**
     * Note: Depends on hibernate implementation details hibernate-core-4.3.7.Final.
     *
     * @see
     * Hibernate
     * Documentation
     * @see TimestampType
     */
    public class JavaUtilDateType
            extends AbstractSingleColumnStandardBasicType
            implements VersionType, LiteralType {
    
        public static final TimestampType INSTANCE = new TimestampType();
    
        public JavaUtilDateType() {
            super(
                    TimestampTypeDescriptor.INSTANCE,
                    new JdbcTimestampTypeDescriptor() {
    
                        @Override
                        public Date fromString(String string) {
                            return new Date(super.fromString(string).getTime());
                        }
    
                        @Override
                        public  Date wrap(X value, WrapperOptions options) {
                            return new Date(super.wrap(value, options).getTime());
                        }
    
                    }
            );
        }
    
        @Override
        public String getName() {
            return "timestamp";
        }
    
        @Override
        public String[] getRegistrationKeys() {
            return new String[]{getName(), Timestamp.class.getName(), java.util.Date.class.getName()};
        }
    
        @Override
        public Date next(Date current, SessionImplementor session) {
            return seed(session);
        }
    
        @Override
        public Date seed(SessionImplementor session) {
            return new Timestamp(System.currentTimeMillis());
        }
    
        @Override
        public Comparator getComparator() {
            return getJavaTypeDescriptor().getComparator();
        }
    
        @Override
        public String objectToSQLString(Date value, Dialect dialect) throws Exception {
            final Timestamp ts = Timestamp.class.isInstance(value)
                    ? (Timestamp) value
                    : new Timestamp(value.getTime());
            // TODO : use JDBC date literal escape syntax? -> {d 'date-string'} in yyyy-mm-dd hh:mm:ss[.f...] format
            return StringType.INSTANCE.objectToSQLString(ts.toString(), dialect);
        }
    
        @Override
        public Date fromStringValue(String xml) throws HibernateException {
            return fromString(xml);
        }
    }
    

    This solution mostly relies on TimestampType implementation with adding additional behaviour through anonymous class of type JdbcTimestampTypeDescriptor.

提交回复
热议问题