Enterprise Java Development@TOPIC@
@PersistenceContext
Injected with EntityManager
Transaction Scoped
persistence context only sees a single Tx
container injects EntityManager with Tx active
Extended Scope
persistence context may see multiple Tx
only relevant for Stateful EJBs
@PersistenceUnit
Injected with EntityManagerFactory
May be used to implement BEAN-managed transactions
Figure 97.1. @PersistenceContext Injection
@Stateless
public class HotelMgmtEJB implements HotelMgmtRemote, HotelMgmtLocal {
@PersistenceContext(unitName="ejbjpa-hotel")
private EntityManager em;
private HotelDAO dao;
private HotelMgmt hotelMgmt;
@PostConstruct
public void init() {
dao = new JPAHotelDAO();
((JPAHotelDAO)dao).setEntityManager(em);
hotelMgmt = new HotelMgmtImpl();
((HotelMgmtImpl)hotelMgmt).setHotelDao(dao);
}
@PersistenceContext.unitName is the name used within the persistence.xml
@PersistenceContext.name would be the ENC name normally defined in ejb-jar.xml
Figure 97.2. @PersistenceUnit Injection
@Singleton
@Startup
@TransactionManagement(TransactionManagementType.BEAN)
public class HotelInitEJB implements HotelInitRemote {
@PersistenceUnit(unitName="ejbjpa-hotel")
private EntityManagerFactory emf;
@Resource
private UserTransaction tx;
@Override
public void businessMethod() {
EntityManager em=emf.createEntityManager();
HotelDAO dao = new JPAHotelDAO();
((JPAHotelDAO)dao).setEntityManager(em);
tx.begin();
em.joinTransaction(); //tells the EM to join the JTA Tx
...
tx.commit();
em.close();
}
}
BEAN-managed transactions means JTA transaction controlled thru injected UserTransaction
Persistence unit (EntityManagerFactory) being injected from a JTA-managed source
i.e., the transaction must be managed at JTA level
Method programmatically controlling scope of JTA transaction
em.joinTransaction() called on EntityManager created outside scope of JTA transaction
Newer technique -- JavaEE's answer to Spring Configuration
Define qualifier annotation
package ejava.examples.jndidemo;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.RetentionPolicy.*;
import static java.lang.annotation.ElementType.*;
import javax.inject.Qualifier;
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface JndiDemo {
}
Define producer of Persistence Context
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
public class SchedulerResources {
@PersistenceContext(name="jndidemo") //using ENC-name
@Produces
@JndiDemo
public EntityManager em;
Define injection point
@Stateless
public class TrainSchedulerEJB
extends SchedulerBase implements TrainSchedulerRemote {
@Inject @JndiDemo
private EntityManager em;