Reputation: 666
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?
Upvotes: 4
Views: 8097
Reputation: 4970
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
Upvotes: 13
Reputation: 1980
@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.
Upvotes: 2