0 Replies Latest reply on Oct 20, 2015 3:00 AM by bhimaraj

    Container Managed Transaction between two session beans in ejb3 and jboss5.0.1.GA

    bhimaraj

      I have three tables server_detail, server_group, server_group_mappping and the entity classes as below. (have not given the full code details)

       

          @Entity

          @Table(name = "server_detail")

          public class ServerBean implements Serializable {

          private static final long serialVersionUID = 1L;

          @Id

          @GeneratedValue(strategy = GenerationType.IDENTITY)

          @Column(name = "server_id")

          private Integer ServerId;

         

          @Column(name = "name")

          private String serverName;

          ....

          }

       

       

          @Entity

          @Table(name = "server_group")

          public class ServerGroupBean implements Serializable {

          private static final long serialVersionUID = 1L;

          @Id

          @GeneratedValue(strategy = GenerationType.IDENTITY)

          @Column(name = "group_id")

          private Integer groupId;

         

          @Column(name = "name")

          private String groupName;

          ....

          }

       

       

          @Entity

          @IdClass(GroupMapPK.class)

          @Table(name = "server_group_mapping")

          public class ServerGroupMapBean implements Serializable {

          private static final long serialVersionUID = 1L;

          @Id

          @Column(name = "group_id")

          private Integer groupId;

          @Id

          @Column(name = "server_id")

          private Integer serverId;

          ....

          }

       

       

      Each Entity Bean class having one wrapper class, to manage operations on entity bean as below

       

       

          @Stateless

          @Local

          public class ServerClient implements ServerLocal {

          @PersistenceContext

          private EntityManager em;

         

          public ServerClient() {

          }

          public ServerBean create(java.lang.String name) {

          ServerBean bean = new ServerBean(name);

          em.persist(bean);

          return bean;

          }

          public ServerBean update(ServerBean bean){

          return (em.contains(bean) ? bean : em.merge(bean));

          }

          public void remove(ServerBean bean) {

          em.remove(em.contains(bean) ? bean : em.merge(bean));

          }

       

       

       

       

          @Stateless

          @Local

          public class ServerGroupClient implements ServerGroupLocal {

          @PersistenceContext

          private EntityManager em;

         

          public ServerGroupClient() {

          }

          public ServerGroupBean create(java.lang.Integer name) {

          ServerGroupBean bean = new ServerGroupBean(name);

          em.persist(bean);

          return bean;

          }

          public ServerGroupBean update(ServerGroupBean bean){

          return (em.contains(bean) ? bean : em.merge(bean));

          }

          public void remove(ServerGroupBean bean) {

          em.remove(em.contains(bean) ? bean : em.merge(bean));

          }

       

       

       

       

          @Stateless

          @Local

          public class ServerGroupMapClient implements ServerGroupMapLocal {

          @PersistenceContext

          private EntityManager em;

         

          public ServerGroupMapClient() {

          }

          public ServerGroupMapBean create(java.lang.Integer serverId,java.lang.Integer groupId ) {

          ServerGroupMapBean bean = new ServerBean(serverId, groupId);

          em.persist(bean);

          return bean;

          }

          public ServerBean update(ServerBean bean){

          return (em.contains(bean) ? bean : em.merge(bean));

          }

          public void remove(ServerBean bean) {

          em.remove(em.contains(bean) ? bean : em.merge(bean));

          }

       

      I am using MYSQL (innoDB Engine) for the tables and the their relation mapping amound the tables.

       

      Now, I have GroupManager session Bean class, which maintains the server_group and server_group_mapping table transactions. When ever i create server group and the members, i have to do following transaction.

       

           1. First, add group id and group name to server_group table

           2. Second, map groupid with server id in server_group_mapping table

       

      Following is the code.

       

          @Stateless

          @Local

          public class GroupManagerBean implements GroupManagerLocal {

          @Resource

          private SessionContext context;

        

          private static GroupLocal GroupLocal;

          private static GroupMapLocal GroupMapLocal;

          public GroupManagerBean() {

          GroupLocal = ServiceLocator.getGroupLocal();

          smscMapLocal = ServiceLocator.getGroupMapLocal();

          }

          public void addGroup(GroupBean bean, Integer serverId){

          group = GroupLocal.create(bean.getGroupName()); ---> 1

          ...

          GroupMapLocal.create(group.getGroupId(), serverId); ----> 2

          }

       

       

      ServiceLocator class is the location where can i lookup all my beans.

      Bydefault, in ejb3 transaction attribute is required. if i execute addGroup() method. m getting following exception.

       

          javax.ejb.EJBTransactionRolledbackException: EntityManager must be access within a transaction

          at org.jboss.ejb3.tx.Ejb3TxPolicy.handleInCallerTx(Ejb3TxPolicy.java:115)

          at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:130)

          at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:194)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:186)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:41)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.ejb3.BlockContainerShutdownInterceptor.invoke(BlockContainerShutdownInterceptor.java:67)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.ejb3.session.SessionSpecContainer.invoke(SessionSpecContainer.java:219)

          at org.jboss.ejb3.proxy.handler.ProxyInvocationHandlerBase.invoke(ProxyInvocationHandlerBase.java:261)

          ....

          Caused by: javax.persistence.TransactionRequiredException: EntityManager must be access within a transaction

          at org.jboss.jpa.deployment.ManagedEntityManagerFactory.verifyInTx(ManagedEntityManagerFactory.java:155)

          at org.jboss.jpa.tx.TransactionScopedEntityManager.persist(TransactionScopedEntityManager.java:186)

          at com.example.GroupClient.create(GroupClient.java:37)

          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

       

      As per the error persistence managers(GroupClient and GroupMapClient) is out of our transaction scope. I would like to know, how can i make the transaction happen completely while injecting the persistence managers into the transaction scope?