本文部分内容节选自Enterprise JavaBeans 3.0 by Bill Burke & Richard Monson-Haefel
4 Persistence
EJB支持声明性事务,事务传播行为可以由TransactionAttribute annotation或者XML配置文件指定。事务属性有下列可选值:NotSupported、Supports、Required、RequiresNew、Mandatory和Never(Srping多支持一个NESTED)。默认的事务属性是Required。
伴随着事务的传播,persistence context也有特定的传播规则:
以下是个简单的例子:
import javax.ejb.Local; @Local public interface StatelessLocal { void doStatelessLocal(Movie m); }
import javax.ejb.Remote; @Remote public interface StatelessRemote { void doStatelessRemote(Movie m); }
import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContextType; import com.versus.ejb.injection.entitymanager.Movie; @Stateless public class StatelessImpl implements StatelessLocal, StatelessRemote { // @PersistenceContext(unitName = "ejb", type = PersistenceContextType.TRANSACTION) private EntityManager entityManager; public void doStatelessLocal(Movie movie) { // System.out.println("in StatelessImpl.doStatelessLocal()"); @SuppressWarnings("unused") Movie m2 = entityManager.find(Movie.class, new Integer(2)); // System.out.println(entityManager.contains(movie)); } public void doStatelessRemote(Movie movie) { // System.out.println("in StatelessImpl.doStatelessRemote()"); @SuppressWarnings("unused") Movie m2 = entityManager.find(Movie.class, new Integer(2)); // System.out.println(entityManager.contains(movie)); } }
import javax.ejb.Local; @Local public interface Stateful1Local { void doStatefulLocal(); }
import javax.ejb.Remote; @Remote public interface Stateful1Remote { void doStatefulRemote(); }
import javax.ejb.EJB; import javax.ejb.Stateful; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContextType; @Stateful public class Stateful1Impl implements Stateful1Local, Stateful1Remote { // @PersistenceContext(unitName = "ejb", type = PersistenceContextType.EXTENDED) private EntityManager entityManager; // @EJB private StatelessLocal statelessLocal; @EJB private StatelessRemote statelessRemote; @EJB private Stateful2Local stateful2Local; @EJB private Stateful2Remote stateful2Remote; public void doStatefulLocal() { // System.out.println("in Stateful1Impl.doStatefulLocal()"); Movie m1 = entityManager.find(Movie.class, new Integer(1)); System.out.println(entityManager.contains(m1)); // statelessLocal.doStatelessLocal(m1); statelessRemote.doStatelessRemote(m1); // stateful2Local.doStatefulLocal(m1); stateful2Remote.doStatefulRemote(m1); } public void doStatefulRemote() { // System.out.println("in Stateful1Impl.doStatefulRemote()"); Movie m1 = entityManager.find(Movie.class, new Integer(1)); System.out.println(entityManager.contains(m1)); // statelessLocal.doStatelessLocal(m1); statelessRemote.doStatelessRemote(m1); // stateful2Local.doStatefulLocal(m1); stateful2Remote.doStatefulRemote(m1); } }
import javax.ejb.Local; @Local public interface Stateful2Local { void doStatefulLocal(Movie m); }
import javax.ejb.Remote; @Remote public interface Stateful2Remote { void doStatefulRemote(Movie m); }
import javax.ejb.Stateful; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContextType; @Stateful public class Stateful2Impl implements Stateful2Local, Stateful2Remote { // @PersistenceContext(unitName = "ejb", type = PersistenceContextType.EXTENDED) private EntityManager entityManager; public void doStatefulLocal(Movie movie) { // System.out.println("in Stateful2Impl.doStatefulLocal()"); @SuppressWarnings("unused") Movie m3 = entityManager.find(Movie.class, new Integer(3)); // System.out.println(entityManager.contains(movie)); } public void doStatefulRemote(Movie movie) { // System.out.println("in Stateful2Impl.doStatefulRemote()"); @SuppressWarnings("unused") Movie m3 = entityManager.find(Movie.class, new Integer(3)); // System.out.println(entityManager.contains(movie)); } }
import java.util.Properties; import javax.naming.Context; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject; public class PersistenceTest { public static void main(String args[]) throws Exception { // Properties properties = new Properties(); properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.LocalInitialContextFactory"); InitialContext ctx = new InitialContext(properties); // if(true) { Object ref1 = ctx.lookup("Stateful1ImplLocal"); Stateful1Local simpleStatefulLocal = (Stateful1Local)PortableRemoteObject.narrow(ref1, Stateful1Local.class); simpleStatefulLocal.doStatefulLocal(); Object ref2 = ctx.lookup("Stateful1ImplRemote"); Stateful1Remote simpleStatefulRemote = (Stateful1Remote)PortableRemoteObject.narrow(ref2, Stateful1Remote.class); simpleStatefulRemote.doStatefulRemote(); } } }
以上代码的输出是:
in Stateful1Impl.doStatefulLocal()
true
in StatelessImpl.doStatelessLocal()
true
in StatelessImpl.doStatelessRemote()
false
in Stateful2Impl.doStatefulLocal()
true
in Stateful2Impl.doStatefulRemote()
false
in Stateful1Impl.doStatefulRemote()
true
in StatelessImpl.doStatelessLocal()
true
in StatelessImpl.doStatelessRemote()
false
in Stateful2Impl.doStatefulLocal()
true
in Stateful2Impl.doStatefulRemote()
false