JPA命名查询与标准API?

是否有针对Criteria APINamedQuery之间决策的启发式/最佳实践/规则集?

到目前为止我的想法:
命名查询通常更具可读性。 条件查询更灵活。
两者都是预编译的。 我倾向于尽可能长时间地使用命名查询,然后更改为条件。

但是,通过使用标准API来“灵活”查询的冲动可能暗示了次优设计(即关注点的分离)?

谢谢

命名查询更加优化(它们被解析/准备一次)。 Criteria查询是动态的(它们不是预编译的,尽管某些JPA提供程序(如EclipseLink)维护标准准备缓存)。

我只会将标准用于动态查询。

例如,当必须基于变量和多个搜索条件动态生成查询时,条件查询是一个不错的选择。

对于静态查询,JPQL更具可读性,我更喜欢使用它们而不是条件查询。 你可能会失去一些安全感,但unit testing应该会让你更自信。

另一个观点是虽然条件查询不是那么可读,但它是类型安全的,因此为您提供编译时类型检查。 如果在有许多实体和许多查询的项目中更改数据库,那么在编译时看到由于更改而导致哪些查询出错是非常有帮助的。

另一方面,我不确定这比JPQL的简单性更有益

我实际上经历了Hibernate(4.3.0-SNAPSHOT)源代码和EclipseLink(2.5.0-SNAPSHOT)源代码,并查看了每个代码中的JPA实现。

EclipseLink显然不是您描述的方式的线程安全。 具体来说,它会尝试重复重新计算联接。

Hibernate的实现看起来对我来说是线程安全的。 我不是百分百肯定,但似乎确实如此。 我会说,由于未指定,未来不能保证这是真的。

但是,我会警告你,我不认为你会获得太多收益。 从我所看到的,查询的大部分编译实际上是在“createQuery”阶段完成的,所以你甚至不会获得很多缓存结果。

JPA还提供了一种使用@NamedQuery和@NamedQueries注释构建静态查询(如命名查询)的方法。 在可能的情况下,在JPA中优先考虑命名查询而不是动态查询是一种很好的做法。 来自http://www.objectdb.com/java/jpa/query/api