Inject PersistenceContext with CDI

拜拜、爱过 提交于 2019-12-18 07:01:53

问题


Currently, I'm using PersistenceContext to inject an EntityManager. The EM is injected perfectly.

@Stateless
public StatelessSessionBean implements StatelessSessionBeanLocal {

    @PersistenceContext(unitName = "MyPersistenceUnit")
    private EntityManager em;

    @Override
    public Collection<MyObject> getAllObjects(){
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriqQuery<MyObject> query = cb.createQuery(MyObject.class);
        query.from(MyObject);
        return em.createQuery(query).getResultList();
    }
}

Now I try to decorate the bean, and suddenly the em doesn't get injected. I get a NullPointerException.

@Decorator
public StatelessSessionBeanDecorator implements StatelessSessionBeanLocal {

    @Inject
    @Delegate
    @Any
    StatelessSessionBeanLocal sb

    @Override
    public Collection<MyObject> getAllObjects(){
        System.out.println("Decorated method!");
        return sb.getAllObjects();
    }
}

I know EJB and CDI are 2 completely different managers, so the one doesn't know about the other. I'm expecting that @PersistenceContext is an EJB injection point, while @Inject is a CDI one. What should I do to solve this and get the EntityManager to be injected like it should?


回答1:


The best practice for persistence context and CDI is to make them CDI bean to avoid these kind of issue.

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

After that you'll be able to inject the EntityManager in CDI way. Taking your EJB it'll be :

@Stateless
public StatelessSessionBean implements StatelessSessionBeanLocal {

    @Inject
    private EntityManager em;

    @Override
    public Collection<MyObject> getAllObjects(){
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriqQuery<MyObject> query = cb.createQuery(MyObject.class);
        query.from(MyObject);
        return em.createQuery(query).getResultList();
    }
}

This way, you'll be able to decorate your CDI bean with no issue.

If you have multiple EntityManagers you can use CDI qualifiers to distinguish them




回答2:


@PersistenceContext is an EJB injection point, while @Inject is a CDI one

Actually, no. @PersistenceContext annotation can be used in CDI and is not connected with EJB. You can do something like this:

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

    ...

}

EJB uses @EJB annotation to inject other EJB, but it can inject any CDI bean or persistence context with same annotations.



来源:https://stackoverflow.com/questions/27506727/inject-persistencecontext-with-cdi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!