Enterprise Java Development@TOPIC@
@PersistenceContext
Injected with EntityManager
Transaction Scoped (default)
persistence context only sees a single Tx
container injects EntityManager with Tx active
@PersistenceContext(unitName="ejbjpa-hotel", type=PersistenceContextType.TRANSACTION)
private EntityManager em;
Extended Scope
persistence context may see multiple Tx
only relevant for Stateful EJBs
@PersistenceContext(unitName="ejbjpa-hotel", type=PersistenceContextType.EXTENDED)
private EntityManager em;
@PersistenceUnit
Injected with EntityManagerFactory
May be used to implement BEAN-managed transactions
@PersistenceContext.unitName is the name used within the persistence.xml
@PersistenceContext.name would be the ENC name normally defined in ejb-jar.xml
@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.synchronization
SynchronizationType.SYNCHRONIZED (default) -- EntityManager automatically joined with jtaTransaction
SynchronizationType.UNSYNCHRONIZED -- EntityManager manually joined with jtaTransaction. Useful for Stateful Session EJBs where interaction with EntityManager may span multiple client method calls.
@PersistenceContext.type
PersistenceContextType.TRANSACTION (default) - EntityManager transactions automatically managed by container and will invoke each root method once per transaction
PersistenceContextType.EXTENDED - EntityManager transactions may span multiple calls. Useful for Stateful Session EJBs to retain state during a complete session
Persistence unit (EntityManagerFactory) being injected from a JTA-managed source
i.e., the transaction must be managed at JTA level
BEAN-managed transactions means JTA transaction controlled thru injected UserTransaction
Method programmatically controlling scope of JTA transaction
em.joinTransaction() called on EntityManager created outside scope of JTA transaction
@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();
}
}
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(unitName="jndidemo")
@Produces
@JndiDemo
public EntityManager em;
Define injection point
@Stateless
public class TrainSchedulerEJB
extends SchedulerBase implements TrainSchedulerRemote {
@Inject @JndiDemo
private EntityManager em;
The Qualifier annotation is only necessary when the deployed application contains multiple producers of an EntityManager.