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

2022-09-03 05:17:15

我有一个关于毫秒日期管理的问题。我理解需要使用TIMESTAMP来存储毫秒:

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

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

java.util.Date newDate = new Date(this.date.getTime());
this.date.equals(newDate) == false
newDate.equals(this.date) == true

我尝试在持久性类中修改我的方法:

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

它正在工作,但对于大量数据来说效率不高。

还有其他选择:

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

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

你有没有遇到过这个问题?我做错了什么?处理此问题的最佳方法是什么?


答案 1

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

要将 SQL 映射到 ,Hibernate 使用实际上会为您的属性分配一个 java.sql.Timestamp。虽然这是“合法的”,但问题是这不是对称的(为什么在地球上?!),这打破了.TIMESTAMPjava.util.DateTimestampTypejava.util.DateTimestamp.equals(Object)Date.equals(Object)

因此,你不能“盲目”使用 如果映射到 SQL ,这当然是不可接受的。myDate.equals(someRealJavaUtilDate)myDateTIMESTAMP

但是,尽管这在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);
   }

}

答案 2

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

简而言之 - 并且是相互可比的。java.util.Datejava.sql.Timestamp

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

甚至更进一步 - 您可以使用字段来存储日期。甚至一个(从joda时间)longDateTime