我有一个目标是保存时间戳的列,该时间戳使用java.util.Date数据类型定义并存储在数据库中的Oracle DATE类型中。我已经验证了从数据库中正确保存和检索完整的日期和时间信息,但是当我尝试在NamedQuery中对它进行比较时,时间信息似乎在比较中没有考虑到。
该列定义如下(analyzeDate的类型为java.util.Date):
@Basic(optional = false)
@Column(name = "ANALYZE_DATE")
@Temporal(TemporalType.TIMESTAMP)
private Date analyzeDate;
我的命名:
@NamedQuery(name = "BOADocument.findByBeforeAnalyzeDate",
query = "SELECT b FROM BOADocument b WHERE b.companyId = :companyId AND b.analyzeDate < :analyzeDate")
然后我执行,传递analyzeDate,类型为java.util.Date:
List<BOADocument> docs = em.createNamedQuery("BOADocument.findByBeforeAnalyzeDate")
.setParameter("companyId", clientRecord)
.setParameter("analyzeDate", analyzeDate, TemporalType.TIMESTAMP)
.getResultList()
我找回了Document表中所有行的列表,尽管它们对于analyzeDate的值都与我设置为NamedQuery的参数的值完全相同。
如果我反过来比较,我没有得到任何线条,进一步说服时间戳的时间部分在b.analyzeDate方面丢失,而不是:analyzeDate方面。
我正在使用JPA 1.0和Hibernate 3.5。
这让我很难过,而且我已经接近放弃并使用原生查询了,但这就像是作弊!
答案 0 :(得分:3)
事实证明,底层的Oracle类型必须是TIMESTAMP。
DATE持有小时,分钟和秒信息。这对我来说足够精确,所以我打算使用它而不是TIMESTAMP,它也持有毫秒。正如我之前提到的,存储和检索DATE的小时,分钟和秒信息是完美的,但不能根据命名查询中的时间数据进行比较。
我改变了数据库列的类型,瞧,以前编写的代码工作。当然,我也节省了毫秒数,但这并没有在我的代码中出现任何副作用。
答案 1 :(得分:1)
将查询修改为以下
SELECT b FROM BOADocument b WHERE b.companyId =:companyId AND CAST(b.analyzeDate AS TIMESTAMP)&lt; :analyzeDate”