JPA Named Queries vs Criteria API?

2020-02-20 07:36发布

问题:

Is there a heuristic/best practice/ruleset for a decision between the Criteria API and NamedQuery?

My thoughts so far :
Named queries are generally more readable. Criteria queries are more flexible.
Both are precompiled. I tend to rely on using named queries as long as possible, then changing to criteria.

But maybe the urge to "flexify" the query by using the criteria API is a hint to suboptimal design (i.e. separation of concerns)?

Thank you

回答1:

Named queries are more optimal (they are parsed/prepared once). Criteria queries are dynamic, (they are not precompiled, although some JPA providers such as EclipseLink maintain a criteria prepare cache).

I would use criteria only for dynamic queries.



回答2:

Criteria queries are a good choice when a query must be generated dynamically, based of variable and multiple search criteria, for example.

For static queries, JPQL is much more readable, and I prefer using them than criteria queries. You could lose some safety, but the unit tests should make you more confident.



回答3:

Another viewpoint is that although criteria query is not so readable, it is typesafe, therefore provides you compile time type checking. If you change the database in projects where there are many entities and many queries, it is really helpful to see at compile time what queries went wrong because of the change.

On the other hand, I'm not sure that is more beneficial than the simpleness of JPQL



回答4:

I actually went through the Hibernate (4.3.0-SNAPSHOT) source and the EclipseLink (2.5.0-SNAPSHOT) source and looked through the JPA implementation in each.

EclipseLink is clearly not thread safe in the manner you describe. Specifically it tries to recalculate joins repeatedly.

Hibernate's implementation looks thread safe to me. I'm not 100% sure, but it does seem to be. I would say that this is not guaranteed to be true in the future since it isn't specified.

However, I will warn you, I don't think you're going to gain much. From what I'm looking at, much of the compilation of the query is actually done during the "createQuery" phase so you wouldn't even gain much caching the results.



回答5:

JPA also provides a way for building static queries, as named queries, using the @NamedQuery and @NamedQueries annotations. It is considered to be a good practice in JPA to prefer named queries over dynamic queries when possible. From http://www.objectdb.com/java/jpa/query/api