14 Replies Latest reply on Dec 28, 2006 7:37 AM by Marcel Almeida

    Open Session in View in EJB3

    Johan Persson Newbie

      I'm trying to get my head around how to implement the open-session-in-view
      pattern in EJB3.

      Normally this is done by having an interceptor and letting this close and
      commit the session resp. transaction at the end of the http-request.

      But since all ejb-calls are treated as isolated transactions and at the end of
      the method the transaction and the session is commited and closed. So when control is giving back to the view (in our case a struts-action) the session is already closed, and the objects returned are detached.

      How is this pattern typically implemented in a EJB3-environment? I've seen
      people recommending implementing seperate methods for retreaving the lazy objects needed, but to me is this not really a good solution, and would really prefer to have the possibility to load the lazy objects and collection on the fly.

      Cheers
      Johan

        • 1. Re: Open Session in View in EJB3
          Bill Burke Master

           

          "surak" wrote:
          I'm trying to get my head around how to implement the open-session-in-view
          pattern in EJB3.

          Normally this is done by having an interceptor and letting this close and
          commit the session resp. transaction at the end of the http-request.


          Are you opening/closing up a JTA transaction in the Servlet Filter? If so, then you don't have to do anything as the JTA transaction will be propagated to the EJB that is interacting with the EntityManager. If not, then you have to do your own plumbing and can use an EXTENDED persistence context:

          EntityManagerFactory.createEntityManager(EXTENDED)

          will give you an EntityManager who's persistence context (and managed objects) will last beyond the life of the JTA transaction. If you don't want to manage the lifecycle you can use a Stateful Session Bean to do this:

          @Stateful
          public class MyConverationBean ... {

          @PersistenceContext(type=EXTENDED)
          private EntityManager manager;

          }

          You get me? or maybe I'm not offering a good solution.




          • 2. Re: Open Session in View in EJB3
            Gavin King Master

            To use open session in view you will need a client demarcated transaction. It simply can't be done using EJB declarative transaction management.

            This is one of the problems that Seam is designed to solve:

            http://www.jboss.com/products/seam

            • 3. Re: Open Session in View in EJB3
              Johan Persson Newbie

               

              "bill.burke@jboss.com" wrote:
              "surak" wrote:
              I'm trying to get my head around how to implement the open-session-in-view
              pattern in EJB3.

              Normally this is done by having an interceptor and letting this close and
              commit the session resp. transaction at the end of the http-request.


              Are you opening/closing up a JTA transaction in the Servlet Filter? If so, then you don't have to do anything as the JTA transaction will be propagated to the EJB that is interacting with the EntityManager. If not, then you have to do your own plumbing and can use an EXTENDED persistence context:

              EntityManagerFactory.createEntityManager(EXTENDED)

              will give you an EntityManager who's persistence context (and managed objects) will last beyond the life of the JTA transaction. If you don't want to manage the lifecycle you can use a Stateful Session Bean to do this:

              @Stateful
              public class MyConverationBean ... {

              @PersistenceContext(type=EXTENDED)
              private EntityManager manager;

              }

              You get me? or maybe I'm not offering a good solution.




              Should it be enough to begin a JTA-transaction in the filter? Just to try it out I wrote a filter that looks up the EntityManagerFactory from jndi and creates a new EntityManager from which I do getTransaction upon which I call begin().

              But even after doing this I get a LazyException when trying to get a lazy collection, so it seems like the session is still being closed after the bean-method is executed.

              I looked at the Seam-project, as suggested by Gavin, which seems to be really great, but unfortunally is it a bit late in our project to switch to JSF now.

              • 4. Re: Open Session in View in EJB3
                Bill Burke Master

                THis should work. I will try to reproduce when I get a chance. In the meantime, could you post a jira task with a sample app that uses the filter to create a JTA transaction and reproduces your problem? It would make things go faster on my end.

                • 5. Re: Open Session in View in EJB3
                  Emmanuel Bernard Master

                  em.getTransaction().begon() does not start a JTA tx, but a regular resource Tx.

                  • 6. Re: Open Session in View in EJB3
                    Johan Persson Newbie

                     

                    "bill.burke@jboss.com" wrote:
                    THis should work. I will try to reproduce when I get a chance. In the meantime, could you post a jira task with a sample app that uses the filter to create a JTA transaction and reproduces your problem? It would make things go faster on my end.


                    I just created a sample-app and attached this to the following JIRA-task.

                    http://jira.jboss.com/jira/browse/EJBTHREE-299

                    The affected code is included and displays the failure.

                    Thanks for your help!
                    Johan

                    • 7. Re: Open Session in View in EJB3
                      Johan Persson Newbie

                       

                      "epbernard" wrote:
                      em.getTransaction().begon() does not start a JTA tx, but a regular resource Tx.


                      Thanks very much for pointing this out! I'm now starting a real JTA-tx and the lazy loading is now working a tiny bit better ;)

                      Cheers
                      Johan

                      • 8. Re: Open Session in View in EJB3
                        Grzegorz Knapczyk Newbie

                        Could you please explain how to start JTA-tx? I tried with the following code:

                         EntityManagerFactory factory = (EntityManagerFactory)
                         portal.ActionServlet.ctxLookup("java:/EntityManagerFactories/manager1");
                        
                         EntityManager manager = factory.createEntityManager(PersistenceContextType.EXTENDED);
                         EntityTransaction transaction = manager.getTransaction();
                        
                         transaction.begin();
                        
                        // here is the part where I try to use some LAZY fetched properties, but the exception is thrown
                        
                         transaction.commit();
                        


                        The exception is:
                        org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role:
                        PrRecord.modifications, no session or session was closed
                        



                        • 9. Re: Open Session in View in EJB3
                          Bill Burke Master

                          javax.transaction.UserTransaction ut = (UserTransaction)initialContext.lookup("java:/UserTransaction");

                          • 10. Re: Open Session in View in EJB3
                            Grzegorz Knapczyk Newbie

                            Thanks for your quick reply. I have tried with javax.transaction.UserTransaction, but it still doesn't work. Server throws the exception LazyInitializationException.

                            javax.transaction.UserTransaction ut = (UserTransaction)initialContext.lookup("java:comp/UserTransaction");
                            ut.begin();
                            (...) // here I try to use LAZY propererty, but the exeption is thrown
                            ut.commit();

                            10:25:21,950 ERROR [LazyInitializationException] failed to lazily initialize a collection of role: org.aplusc.tvman.ejb.entity.PrRecord.modifications, no session or session was closed


                            • 11. Re: Open Session in View in EJB3
                              Holger Moosbauer Newbie

                              I got the same problem an spinning my head around but can't find any proper or running solution ... my code is

                              struts action

                              InitialContext initialContext = ServiceLocator.getInitialContext();
                               usertransaction = (UserTransaction)initialContext.lookup("UserTransaction");
                              
                               usertransaction.begin();
                               IEventService eventService = ServiceFactory.getEventService();
                               Event event = eventService.findEventById(44l);
                              
                              
                               System.out.println(event.getEventCompetitors().size());
                               usertransaction.commit();


                              • 12. Re: Open Session in View in EJB3
                                Holger Moosbauer Newbie

                                session bean

                                @TransactionAttribute(TransactionAttributeType.MANDATORY)
                                 public Event findEventById(long id) throws EJBException {
                                 return entityManager.find(Event.class, id);
                                 }


                                Does anyone know why this is not running properly, of course with the FAMOUS LazyInitializationException ... any help would be gr8 ... thx in advance

                                • 13. Re: Open Session in View in EJB3
                                  Emmanuel Bernard Master

                                  if you can wrap that in a minimal reproducable test case, please post a JIRA issue

                                  • 14. Re: Open Session in View in EJB3
                                    Marcel Almeida Newbie

                                    I have a important doubt on this issue.
                                    If I understood correctly from the Jira Issue (EJBTHREE-299), we can only use the Entity Manager in a Open Session in View style if the EJB are @Local, is it?
                                    Isn´t there any other option for the @Remote beans?