Can the same CriteriaBuilder (JPA 2) instance be used to create multiple queries?
This seems like a pretty simple question, but I have not managed to find a definitive answer yet. I have a DAO class, which is naturally querying the database by using criteria queries. So I would like to know if it is safe to use the same CriteriaBuilder implementation for the creation of different queries or do I have to create new CriteriaBuilder instance for each query. Following code example should illust开发者_StackOverflowrate what I would like to do:
public class DAO() {
CriteriaBuilder cb = null;
public DAO() {
cb = getEntityManager().getCriteriaBuilder();
}
public List<String> getNames() {
CriteriaQuery<String> nameSearch = cb.createQuery(String.class);
...
}
public List<Address> getAddresses(String name) {
CriteriaQuery<Address> nameSearch = cb.createQuery(Address.class);
...
}
}
Is it ok to do this?
Reading the javadoc in section 3.1.1 EntityManager Interface of the JPA 2.0 specification (JSR 317):
/** * Return an instance of CriteriaBuilder for the creation of * CriteriaQuery objects. * @return CriteriaBuilder instance * @throws IllegalStateException if the entity manager has * been closed */ public CriteriaBuilder getCriteriaBuilder();
And this comment just after:
The
Query
,TypedQuery
,CriteriaBuilder
,Metamodel
, andEntityTransaction
objects obtained from an entity manager are valid while that entity manager is open.
And the section 6.5 Constructing Criteria Queries
The
CriteriaBuilder
interface is used to constructCriteriaQuery
objects. TheCriteriaBuilder
implementation is accessed through thegetCriteriaBuilder
method of theEntityManager
orEntityManagerFactory
interface.
I expect being able to reuse a single CriteriaBuilder
to create many queries for the lifetime of the entity manager. But that's my interpretation. However, my initial testing seems to confirm there is nothing wrong with that (the contrary would be indeed horrible).
Interesting question. I would say "of course, that's the whole point of criteriaqueries", but I did not find a single word to back this in here: http://java.sun.com/javaee/6/docs/tutorial/doc/gjivm.html
However: if they weren't reuseable, that would mean that the entitymanager actually modifies them, which would be awful api design. So: I hope they are reuseable, but I can't guarantee it
This is safe.
You can get the CriteriaBuilder from the EntityManagerFactory. In the hibernate implementation, the criteriaBuilder is an instance's field of the EntityManagerFactory. So in traditional cases, there is no risk.
Eclipse Link generates errors (EclipseLink-6089, org.eclipse.persistence.exceptions.QueryException) in a random fashion (sometime it works, sometime not) when you start a query, then another one before you execute the first. See Stack Overflow and JBoss issues for details.
No problem to reuse the CriteriaBuilder if you run your queries one by one or if you plan to use Hibernate.
精彩评论