使用CDI注入PersistenceContext

目前,我正在使用PersistenceContext来注入EntityManager。 EM完美注入。

@Stateless public StatelessSessionBean implements StatelessSessionBeanLocal { @PersistenceContext(unitName = "MyPersistenceUnit") private EntityManager em; @Override public Collection getAllObjects(){ CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriqQuery query = cb.createQuery(MyObject.class); query.from(MyObject); return em.createQuery(query).getResultList(); } } 

现在我尝试装饰豆子,突然间em没有被注射。 我得到一个NullPointerException。

 @Decorator public StatelessSessionBeanDecorator implements StatelessSessionBeanLocal { @Inject @Delegate @Any StatelessSessionBeanLocal sb @Override public Collection getAllObjects(){ System.out.println("Decorated method!"); return sb.getAllObjects(); } } 

我知道EJB和CDI是两个完全不同的管理器,所以那个人不了解另一个。 我期望@PersistenceContext是一个EJB注入点,而@Inject是一个CDI注入点。 我该怎么做才能解决这个问题并让EntityManager像它应该注入一样?

持久化上下文和CDI的最佳实践是使它们成为CDI bean以避免这类问题。

 public class MyProducers { @Produces @PersistenceContext(unitName = "MyPersistenceUnit") private EntityManager em; } 

之后,您将能够以CDI方式注入EntityManager 。 拿你的EJB它将是:

 @Stateless public StatelessSessionBean implements StatelessSessionBeanLocal { @Inject private EntityManager em; @Override public Collection getAllObjects(){ CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriqQuery query = cb.createQuery(MyObject.class); query.from(MyObject); return em.createQuery(query).getResultList(); } } 

这样,您就可以毫无问题地装饰您的CDI bean。

如果您有多个EntityManagers ,则可以使用CDI限定符来区分它们

@PersistenceContext是一个EJB注入点,而@Inject是一个CDI注入点

实际上,没有。 @PersistenceContext注释可以在CDI中使用,并且不与EJB连接。 你可以这样做:

 @Named public class EntityDAO { @PersistenceContext private EntityManager manager; ... } 

EJB使用@EJB注释来注入其他EJB,但它可以使用相同的注释注入任何CDI bean或持久性上下文。