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?
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
@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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With