Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 illustrate 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?

like image 215
pkainulainen Avatar asked May 19 '10 09:05

pkainulainen


4 Answers

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, and EntityTransaction 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 construct CriteriaQuery objects. The CriteriaBuilder implementation is accessed through the getCriteriaBuilder method of the EntityManager or EntityManagerFactory 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).

like image 188
Pascal Thivent Avatar answered Oct 11 '22 19:10

Pascal Thivent


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

like image 20
Sean Patrick Floyd Avatar answered Oct 11 '22 18:10

Sean Patrick Floyd


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.

like image 20
Manuel Avatar answered Oct 11 '22 19:10

Manuel


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.

like image 37
user327961 Avatar answered Oct 11 '22 18:10

user327961