Inject PersistenceContext with CDI
I am currently using PersistenceContext to inject EntityManager. EM is perfectly injected.
@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 am trying to decorate the bean and suddenly em is not injected. I am getting 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 that EJB and CDI are 2 completely different managers, so nobody knows about the other. I expect @PersistenceContext to be the injection point of the EJB and @Inject to be the CDI. What should I do to solve this problem and get the EntityManager to be injected as it should?
source to share
Best practice for persistence and CDI context is to make them CDI bean to avoid this kind of problem.
public class MyProducers {
@Produces
@PersistenceContext(unitName = "MyPersistenceUnit")
private EntityManager em;
}
You will then be able to enter EntityManager
in CDI mode. Taking your EJB this would 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 can decorate your CDI bean without any problem.
If you have multiple EntityManagers
, you can use CDI qualifiers to differentiate them
source to share
@PersistenceContext is the EJB entry point and @Inject is the CDI
Actually, no. Annotations @PersistenceContext
can be used in CDI and are not associated with EJBs. You can do something like this:
@Named
public class EntityDAO {
@PersistenceContext
private EntityManager manager;
...
}
An EJB uses annotation @EJB
to inject another EJB, but can insert any CDI bean or persistence context with the same annotations.
source to share