Reputation: 1034
I have one question concerning JPA: Is there a way to simulate DetachedCriteria (from Hibernate) using the api of JPA 2.0 ?
And if there is a way which classes I need to extend in order to achieve this?
I'm using hibernate 3.6.5 and hibernate-jpa-2.0-api-1.0.0.Final.
Upvotes: 2
Views: 3703
Reputation: 23105
In hibernate you create a DetachedCriteria object outside a Hibernate Session and then attach it to a later Session for execution.
In summary - EJB-style JPA EntityManagers (with container-managed PersistenceContext) can create a Query object that automatically behaves similarly to Hibernate DetachedCriteria, but "core java" style EntityManagers (i.e. application managed) can never create Queries that behave similarly to Hibernate DetachedCriteria.
JPA's PersistenceContext is equivalent to a Hibernate Session.
JPA's Query is equivalent to a DetachedCriteria.
A JPA EntityManager may or may not have a PersistenceContext present at any moment. There are three types of EntityManager:
Under cases (1) and (2) the EntityManager can create a Query (via em.createQuery() method) at any time. Later, when a PC exists, the query can be run. This is identitcal behaviour to Hibernate. Under case (3) there is no equivalent to Hibernate DetachedCriteria.
Don't be scared by the fact I mentioned EJBs here. They are trivially easy to implement and are basically just POJOs with some extra annotations added and some App Server functionality invisibly added to make them "bigger, faster, stronger" than POJOs.
An example of (2):
@Stateful
class MyStatelessEJB {
// Entity Manager is automatically created and injected
// persistent unit name is in persistence.xml
@PersistenceContext(unitName="myPersistenceUnitName",type=PersistenceContextType.EXTENDED)
EntityManager em;
Query q1 = null;
Query q2 = null;
@NOT_SUPPORTED // no transaction or PC here
public methodA() {....
q1 = em.createQuery(...); // create query anyway
q2 = em.createTypedQuery(...);
...}
public methodB() {.... q.execute(); ...} // transaction & PC here - just use Query
@Remove
// when this method is completes the EJB Session ends
public methodC() {.... List<Foo> fooList = q.execute().getResultList; ...}
}
An example of (1) (Stateless Session Bean with Transaction scoped PC) would look similar, but would have no instance variables because it is stateless. The EntityManager & Query would have to be either created and stored as local variables within each method, or would have to be passed/transferred to another stateful EJB where they could be stored.
Upvotes: 3