@PersistenceContext和静态属性

1 jpa glassfish java-ee

现在是时候问一下关于JPA的noob问题了.

我有一个简单的应用程序,所以想为我的所有实体制作一个简单的dao类.

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();
}
}
Run Code Online (Sandbox Code Playgroud)

我试着像这样使用它:

testEntitys =GenericDAO.getAll(TestEntity.class);
Run Code Online (Sandbox Code Playgroud)

但它使用NullPointerException来破坏getAll()中的"em",因此看起来它没有像我预期的那样使用@PersistanceContext设置.

当我在托管bean中使用它时@PersistanceContext工作正常:

@ManagedBean
@SessionScoped
public class TestBean {


    @PersistenceContext(unitName="TestAppPU")
    public EntityManager em;

...    
testEntitys = em.createQuery("select t from TestEntity t").getResultList();
...
Run Code Online (Sandbox Code Playgroud)

所以看起来persistance.xml配置正确.但我不想将em传递给GenericDAO.

所以我的问题是如何按照我的预期(第二个代码示例)实现@PersistanceContext工作GenericDAO并且确实可行,或者我应该在每个我想使用持久性的bean中注入dao类?

str*_*ine 5

注入EntityManagerGenericDAO有没有工作,因为GenericDAO没有被管理.相反,如果类是会话bean或托管bean,那么注入就可以了.

除此之外,还有其他几点需要注意

  • 创建一个EntityManager并不是一个昂贵的操作.因此,当您想要对实体进行操作时,您可以只注入EntityManager所需的类并直接使用方法EntityManager.(旁注:EM应避免注入servlet)
  • GenericDAO似乎没有提供太多.EntityManager已经足够通用了,你可以直接使用它.
  • 最后,关于使用static变量和方法的警告.为了可测试性和线程安全性,我建议反对它.

使用注入DAO的@Statelessbean EntityManager是一种常见做法.

总而言之,您可以简单地注入EM任何需要执行实体操作的类,甚至不使用DAO.如果您希望分离关注点,您可以将一个Statelessbean EM注入DAO