Java 如何使用JPA CriteriaBuilder指定时态类型?

Java 如何使用JPA CriteriaBuilder指定时态类型?,java,jpa,Java,Jpa,我有一个表,该表的列类型为dateTime(我使用的是SQL Server)。我想按dateTime列查询表。我希望dateTime列中的行具有相同的日期或更晚的日期,但我希望将日期作为参数。简而言之,dateTime必须大于或等于指定的日期 我遇到的问题是,当我尝试使用CriteriaAPI查询Date对象时,它只给出第二天的行。我怀疑它试图查找具有相同毫秒或更高毫秒的行。在JPA查询语言中,我可以指定参数的时态类型(setParameter(“dateColumn”,myDate,Tempo

我有一个表,该表的列类型为dateTime(我使用的是SQL Server)。我想按dateTime列查询表。我希望dateTime列中的行具有相同的日期或更晚的日期,但我希望将日期作为参数。简而言之,dateTime必须大于或等于指定的日期

我遇到的问题是,当我尝试使用CriteriaAPI查询Date对象时,它只给出第二天的行。我怀疑它试图查找具有相同毫秒或更高毫秒的行。在JPA查询语言中,我可以指定参数的时态类型(setParameter(“dateColumn”,myDate,Temporal.DATE)),但在CriteriaBuilderAPI中找不到类似的东西。有什么建议吗

我的代码当前如下所示:

cb.greaterThanOrEqualTo(r.<Date>get(fieldName), beginDate));
cb.greaterThanOrEqualTo(r.get(fieldName),beginDate));

如果我使用DataNucleus JPA运行下面的类

@Entity
public class A
{
    @Id
    Long id;

    @Temporal(TemporalType.DATE)
    Date date;
}
它将日期存储在日期列中。然后运行以下查询

SELECT a FROM A a WHERE a.date >= :myDate"
它将java.util.Date作为参数(包括小时/分钟/秒)传入,创建一个

SELECT 'org.datanucleus.test.A' AS NUCLEUS_TYPE,A."DATE",A.ID,A."NAME" FROM A A WHERE A."DATE" >= <2009-06-15>
选择'org.datanucleus.test.A'作为NUCLEUS_类型,A.“日期”、A.ID、A.“名称”,其中A.“日期”>=
其中,是JDBC的一个参数(尖括号仅表示这一点),我没有遇到任何问题,即它正确地将参数解释为与它所比较的类型相匹配(这是JPA规范所暗示的)


显然,如果Hibernate对此有问题,您可以传入一个java.sql.Date,并在Hibernate上引发一个bug,因为我还没有得到答案,我将假设现在除了在应用程序中以编程方式之外,还有其他方法可以解决这个问题


如果我想查询在本周星期一之后创建的实体,我必须创建一个日期对象,将日期设置为星期一,并清除日期对象中的小时、分钟、秒和毫秒。ApacheCommonsLang库为这种情况提供了一个名为DateUtils的助手类。它具有方法truncate,可用于从日期对象中获取不必要的准确性,因此您可以在CriteriaBuilder中使用GreatedThaneQual。

您可以使用参数表达式:

ParameterExpression<Calendar> beginDateParameter = cb.parameter(Calendar.class);
...
...
criteriaQuery.select(...)
  .where(criteriaBuilder.equal(r.get(fieldName), beginDateParameter));

entityManager.createQuery(criteriaQuery)
     .setParameter(beginDateParameter, beginDate, TemporalType.DATE)
     .getResultList(); 

任何实现都应该知道如何指定“dateColumn”,并相应地生成查询。那么为什么不打印生成的SQL呢?生成的SQL是这样的:dateColumn>=?1如果我启用org.hibernate.type的日志记录,我会发现参数确实是一个日期,这对我没有任何帮助。问题是date对象太“精确”,因为它还包含小时、分钟、秒和毫秒。我可以通过删除日期中不必要的部分来修复它,但我想知道您是否可以使用JPA CriteriaBuilder自动完成。对不起,我问的问题实际上与您的回答相反:)。实体A的日期属性将是TemporaltType.TIMESTAMP。我想知道是否有一种方法可以说我给查询的参数将具有TemporalType.DATE。如果指定一个字段作为时间戳,那么它将存储所有数据,因此标准JPQL和标准JPQL将始终使用完整日期。所以不,只需传入java.sql.Date
TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [0] as [DATE]