如何使用java.sql.Timestamp作为真正的java.util.Date与JPA

che*_*kaf 14 java datetime persistence jpa

我有一个关于日期管理的问题,以毫秒为单位.我理解需要使用TIMESTAMP来存储毫秒:

@Temporal(TIMESTAMP)
@Column(name="DATE_COLUMN", nullable = false)
@Override public java.util.Date getDate() { return this.date; }
Run Code Online (Sandbox Code Playgroud)

但是如果我不能将这个日期与java.util.Date的另一个实例进行比较,除非我注意equals()调用的顺序,因为this.dateinstance是一个java.sql.Timestamp.如何从JPA获取java.util.Date?因为来自JPA的日期,即使方法签名是java.util.Date,实际上也是java.sql.Timestamp的一个实例.

java.util.Date newDate = new Date(this.date.getTime());
this.date.equals(newDate) == false
newDate.equals(this.date) == true
Run Code Online (Sandbox Code Playgroud)

我试图在持久化类中修改我的方法:

@Override
public Date getDate() {
  return this.date == null ? null : new Date(this.date.getTime());
}
Run Code Online (Sandbox Code Playgroud)

它工作正常,但是大量数据效率不高.

还有其他选择:

  • 我可以修改我的持久化类的设计,@PostLoad以便在我检索它之后从持久的日期创建一个java.util.Date.

  • 我想知道我是否无法使用ClassTransformer

你有没有遇到过这个问题?我不正确的是什么?处理这个问题的最佳方法是什么?

Pas*_*ent 12

TBH,我不确定这个的确切状态,但是Hibernate(这是你的JPA提供者,对吧?)处理TIMESTAMP列的方式可能确实存在问题.

要将SQL映射TIMESTAMP到a java.util.Date,Hibernate会使用TimestampType实际java.sql.Timestamp为您的java.util.Date属性分配的SQL .虽然这是"合法"的,问题是,Timestamp.equals(Object)不是对称的(为什么地球上?!),这打破的语义Date.equals(Object).

因此,myDate.equals(someRealJavaUtilDate)如果myDate映射到SQL TIMESTAMP,则不能"盲目地"使用,这当然不是真正可以接受的.

但是虽然这已经在Hibernate论坛上进行了广泛的讨论,例如在这个线程这个(阅读所有页面)中,似乎Hibernate用户和开发人员从未就此问题达成一致(参见HB-681等问题)而我只是明白为什么.

也许这只是我,也许我只是为其他人遗漏了一些简单的东西,但问题看起来很明显,而我认为这个愚蠢java.sql.Timestamp是罪魁祸首,我仍然认为Hibernate应该保护用户不受此问题的影响.我不明白为什么加文不同意这一点.

我的建议是创建一个演示问题的测试用例(应该非常简单)并再次报告问题,看看你是否从当前团队获得更多积极的反馈.

同时,您可以使用自定义类型自行"修复"问题,使用类似的东西(从论坛中获取并按原样粘贴):

public class TimeMillisType extends org.hibernate.type.TimestampType {

    public Date get(ResultSet rs, String name) throws SQLException {
        Timestamp timestamp = rs.getTimestamp(name);
        if (timestamp == null) return null;
        return
            new Date(timestamp.getTime()+timestamp.getNanos()/1000000);
   }

}
Run Code Online (Sandbox Code Playgroud)


Boz*_*zho 7

java.sql.Timestamp覆盖该compareTo(Date)方法,因此使用时应该没问题compareTo(..)

总之 - java.util.Datejava.sql.Timestamp相互比较.

此外,您始终可以比较date.getTime()对象本身,而不是对象本身.

更进一步 - 您可以使用long字段来存储日期.甚至是DateTime(从joda-时间)