6 Replies Latest reply on Nov 26, 2008 7:06 PM by plukh

    Share entity bean between stateless session beans

    strunker

      Hi!

      I have a problem with two local stateless session beans and an EntityManager which is used in one of the SLSBs.

      I want the first SLSB to do basic database operations like finding entities and the other one to work with the resulting entities. I attached a small example:


      @Stateless
      public class Bean1 {

      @PersistenceContext(unitName = "UnitName")
      protected EntityManager entityManager;

      public Entity findEntity(...) {
      ...
      }
      }


      @Stateless
      public class Bean2 {

      @EJB
      private Bean1 bean1;

      public User doSomething(...) {
      Entity entity = bean1.findEntity();

      entity.setAnything();
      }
      }


      My problem is that the entity in method doSometing of Bean2 gets detached. So any changes of the entity bean (by calling the setter) are not transacted to database.

      Is this behaviour correct? Is there any way to use a managed entity bean in both SLSBs so that I can use the entity in bean2 the same way as in bean1?

      Hope someone here can help me!

        • 1. Re: Share entity bean between stateless session beans
          wolfgangknauf

          Hi,

          according to the ejb persistence spec (chapter 3.2.4):

          A detached entity may result from transaction commit if a transaction-scoped container-managed entity manager is used (see section 3.3); from transaction rollback (see section 3.3.2); from clearing the persistence context; from closing an entity manager; and from serializing an entity or otherwise passing an entity by value, e.g. to a separate application tier, through a remote interface, etc.


          Does any of those cases apply to your app? You have the special case that the EntityManager is only in "Bean1", so I don't know whether calling a method from "Bean2" means that the persistence context is cleared afterwards.

          Here is something from chapter 5.6.1, but this does not make it much clearer:
          A new persistence context begins when the container-managed entity manager is invoked in the scope of an active JTA transaction, and there is no current persistence context already associated with
          the JTA transaction. The persistence context is created and then associated with the JTA transaction.

          The persistence context ends when the associated JTA transaction commits or rolls back, and all entities that were managed by the EntityManager become detached.

          If the entity manager is invoked outside the scope of a transaction, any entities loaded from the database will immediately become detached at the end of the method call.


          Hope this helps a bit

          Wolfgang

          • 2. Re: Share entity bean between stateless session beans
            strunker

             

            "Wolfgang Knauf" wrote:
            Hi,

            Here is something from chapter 5.6.1, but this does not make it much clearer:
            A new persistence context begins when the container-managed entity manager is invoked in the scope of an active JTA transaction, and there is no current persistence context already associated with
            the JTA transaction. The persistence context is created and then associated with the JTA transaction.

            The persistence context ends when the associated JTA transaction commits or rolls back, and all entities that were managed by the EntityManager become detached.

            If the entity manager is invoked outside the scope of a transaction, any entities loaded from the database will immediately become detached at the end of the method call.



            Thank you for your quick reply. But I don't understand what's going wrong.

            When doSomething of Bean2 is called from an other tier, a new transaction should be created. When in doSomething the method findEntity of Bean1 is called the same transaction should be used and no new one should be generated, because the default transaction type is REQUIRED. So I think that the persistence context should be bound to this transaction and the returned entity should not get detached, but it's not like this.

            Any ideas why this happens?


            • 3. Re: Share entity bean between stateless session beans
              rhodan76

              Please check, that you are using the only the LOCAL-Interface from the bean as reference:

               @EJB
               private LocalBeanInterface bean1;
              


              Instead using the remote-Interface would result in (De-)serialization and those in deteaching any entity.

              • 4. Re: Share entity bean between stateless session beans
                strunker

                 

                "Rhodan76" wrote:
                Please check, that you are using the only the LOCAL-Interface from the bean as reference


                The local and the remote interfaces are the same interface at the moment. But I'll try it with separate interfaces and get back to you.



                • 5. Re: Share entity bean between stateless session beans
                  strunker

                   

                  "Rhodan76" wrote:
                  Please check, that you are using the only the LOCAL-Interface from the bean as reference


                  Ah, it works! Thank you very much.

                  • 6. Re: Share entity bean between stateless session beans
                    plukh

                    How timely! I was just wondering about this same issue. By using local interface in my beans instead of remote, I no longer need to remember to manually merge the changes back. Thanks Rhodan76!