JPA Named Queries vs Criteria API?
Is there a heuristic/best practice/ruleset for a decision between the Criteria API 开发者_如何学JAVAand 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
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.
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.
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
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.
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
精彩评论