JPA Criteria API - 使用Calendar值进行算术运算

时间:2014-10-09 14:16:57

标签: java jpa criteria-api

我正在重写一个巨大的搜索查询,最初是在Hibernate Criteria中创建的。我试图只使用标准的JPA解决方案。我面临的问题是,我想制作一个像这样的where子句:

select ... where (stopTime - startTime) > minimalLength

这似乎不适用于Calendar值,因为我无法使用Criteria API对它们进行算术运算。有解决方案吗?

更新1

正如答案中提到的那样(现在已删除),Criteria API具有sumdiffprod方法,但这些方法的签名为:

<N extends java.lang.Number> Expression<N>
    method(Expression<? extends N> x, Expression<? extends N> y)
<N extends java.lang.Number> Expression<N>
    method(N x, Expression<? extends N> y)
<N extends java.lang.Number> Expression<N>
    method(Expression<? extends N> x, N y)

因此它们不适用于Calendar(甚至Date)。

更新2

我想,我走在正确的轨道上。我决定使用 CriteriaBuilder function方法,并使用它来调用(不幸的是供应商特定的)datediff SQL Server方法。它看起来像这样:

builder.function("datediff", Integer.class, builder.literal("second"), startTime, stopTime)

这个几乎有效,唯一的问题是,datediff不能与 String 一起作为第一个参数,它需要一个关键字(即&# 34;第二个&#34;没有引号)。有没有人知道将文字传递给函数的方法?

3 个答案:

答案 0 :(得分:1)

好吧,最后我放弃了,用HQL代替Criteria API。左,只希望我的问题将在Criteria API的下一次迭代中修复......

答案 1 :(得分:1)

我遇到了同样的问题,遇到了你在更新2中遇到的同样死胡同。

我能想到的唯一解决方法是创建一个不会使用文字&#34;第二个&#34;以及委托给约会者的UDF。

 CREATE FUNCTION [dbo].[datediff_seconds]
 (
    @from datetime,
    @to datetime
 )
 RETURNS int
 AS
 BEGIN

    RETURN datediff(second, @from, @to)

 END

 GO

它是一种kludge,但有效。

答案 2 :(得分:0)

我最终只是简单地转换为unix_timestamp,这是数字并且可以进行差异化。遗憾的是,JPA无法为函数提供参数。

cb.greaterThan(
  cb.diff(
    cb.function("unix_timestamp", Long.class, root.get(Table_.until)),
    cb.function("unix_timestamp", Long.class, root.get(Table_.from))
  )
, 3600L*longerThanHours)