繁体   English   中英

比较 JPA Criteria API 中的日期实体

[英]Compare Date entities in JPA Criteria API

将 JPA 2 与 EclipseLink 实现结合使用。

我正在尝试构建一个动态查询,它应该给我带来一些在给定日期后保留的记录。

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Event> criteria = builder.createQuery(Event.class);
Root<Event> root = criteria.from(Event.class);
criteria.select(root);
criteria.distinct(true);
List<Predicate> predicates = new ArrayList<Predicate>();
//...
if (dateLimit != null){
    ParameterExpression<Date> param = builder.parameter(Date.class, "dateLimit");
    predicates.add(builder.lessThanOrEqualTo(root.get("dateCreated"), param));
}

lessThanOrEqualTo()le()是 API 中仅有的两个方法,在这种情况下看起来可能对我有帮助。 这个警告是由日食引发的:

Bound mismatch: The generic method lessThanOrEqualTo(Expression<? extends Y>, Expression<? extends Y>)
of type CriteriaBuilder is not applicable for the arguments (Path<Object>, ParameterExpression<Date>).
The inferred type Object is not a valid substitute for the bounded parameter
<Y extends Comparable<? super Y>>

我可以想象我没有对这个问题采取正确的方法,但我找不到任何可能解决方案的提示或指示。

问题在于,使用基于字符串的 API,它无法推断get -Operation 结果值的类型。 例如,在Javadoc for Path 中对此进行了解释。

如果你使用

predicates.add(builder.lessThanOrEqualTo(root.<Date>get("dateCreated"), param));

相反,它会工作得很好,因为它可以从类型参数中找出返回类型,并会发现它是可比的。 注意,参数化方法调用的使用root.<Date>get(...) (参见,例如, 参数化方法调用何时有用? )。

另一个(在我看来更好)的解决方案是使用基于元模型的 API 而不是基于字符串的 API。 例如这里给出了一个关于规范元模型的简单例子。 如果你有更多的时间来投资,这是一篇关于静态元模型的好文章: JPA 2.0 中的动态、类型安全查询

您需要使用生成的元模型来访问属性是一种非常安全的方式。 如果您使用字符串来引用您的属性,则只能从调用该方法时使用的显式泛型类型、类型转换或编译器进行的自动类型推断中推导出类型:

Path<Date> dateCreatedPath = root.get("dateCreated");
predicates.add(builder.lessThanOrEqualTo(dateCreatedPath, dateLimit));

我遇到了类似的错误,但语法predicates.add(cb.greaterThan(article.get(Article_.created), since)); 并找到了这个页面。 对我来说,原因是我已将项目从 Java 1.7 升级到 1.8,并且在此过程中还配置了 Maven 以针对 Java 1.8 进行编译。 我只需要将 Maven 编译更改回 1.7,同时将项目的其余部分保持在 1.8,以修复错误。

当我使用谓词时,我遇到了同样的问题。 它适用于除日期类型以外的所有类型。 我尝试了所有方法,对我来说最简单的方法是:

predicates.add(builder.greaterThanOrEqualTo(root.get(criteria.getKey()), (Date)criteria.getValue()));

我在criteria.getValue() (Date)之前添加了(Date) ,这有助于将我的值 Object 识别为 Date 类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM