now its time to ask noob question about JPA.
I've got a simple app, so want to make a simple dao class for all my entities.
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.hibernate.Session;
public class GenericDAO implements Serializable {
public GenericDAO() {
}
@PersistenceContext(unitName="TestAppPU")
public static EntityManager em;
public static <T> void save(T smth) {
em.persist(smth);
}
public static <T> void merge(T smth) {
em.merge(smth);
}
public static <T> void remove(T smth) {
em.remove(smth);
em.flush();
}
public static <T> List<T> getAll(Class<T> cls) {
return (List<T>) ((Session) em.getDelegate()).createCriteria(cls).list();
}
}
I tried to use it like that:
testEntitys =GenericDAO.getAll(TestEntity.class);
But it crushes with NullPointerException about the "em" in getAll(), so it looks like it is not set with @PersistanceContext as I expected.
@PersistanceContext works fine when I use it in the managed bean:
@ManagedBean
@SessionScoped
public class TestBean {
@PersistenceContext(unitName="TestAppPU")
public EntityManager em;
...
testEntitys = em.createQuery("select t from TestEntity t").getResultList();
...
So it looks like persistance.xml is configured right. But I dont want t开发者_JAVA技巧o pass the em to the GenericDAO.
So my question is how to achieve @PersistanceContext working GenericDAO as I expected (second code sample) and does it really possible or I should inject dao classes in every bean where I want to use persistance?
Injecting into EntityManager
into GenericDAO
there did not work because GenericDAO
is not managed. Instead if the class was a session bean or a managed bean, then injection would have worked.
That apart, a few other points to note
- Creating an
EntityManager
is not a costly operation. So when you want to operate on entities you can just inject theEntityManager
on the required class and directly use the methods onEntityManager
. (Sidenote:EM
Injection into servlets is to be avoided ) - This
GenericDAO
doesn't seem to offer much.EntityManager
is already generic enough and you can just directly use it. - Lastly, a warning on the use of
static
variables and methods. I'd advise against it for the sake of testability and thread-safety.
Using @Stateless
beans with EntityManager
injected as DAOs is one common practice.
To summarize, you can simply inject EM
in any class that needs to do entity operations without even using DAOs. If you wished for separation of concerns, you can have a Stateless
bean with EM
injected as a DAO
Spring can understand @PersistenceContext annotations both at field and method level if a PersistenceAnnotationBeanPostProcessor is enabled.
<!-- bean post-processor for JPA annotations -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
As an alternative to defining a PersistenceAnnotationBeanPostProcessor explicitly, consider using the Spring context:annotation-config XML element in your application context configuration.
<!-- post-processors for all standard config annotations -->
<context:annotation-config/>
精彩评论