3 Replies Latest reply on Apr 27, 2009 5:26 PM by gonorrhea

    SFSB + @In leads to LazyInitalizationException

    coresystems_rit

      Hi


      I have a problem with a LazyInitializationException.


      In the authentication handler I load the user from the database in a property which gets outjected for the scope of the session.


      @Stateless
      @Name("authenticator")
      public class AuthenticatorAction implements Authenticator {
           @In
           private EntityManager em;
      
           @Out(required = false, scope = ScopeType.SESSION)
           User currentUser;
      
           public boolean authenticate() {
                ...
                currentUser = (User) em.createQuery("...").getSingleResult();
                ...
           }
      }



      If I know access the currentUser in a differenct bean (SF Bean with Conversation Scope) I get a lazy initialization exception.


      The code which access the currentUser object:


      .setParameter("branches", currentUser.getEmployee().getAssignedBranches()



      and the detailed exception:



      [LazyInitializationException] failed to lazily initialize a collection of role: model.Employee.assignedBranches, no session or session was closed
      org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: model.Employee.assignedBranches, no session or session was closed



      I inject the user into the conversational scoped bean with:


      @In
      private User currentUser;



      I know that the AuthenticatorAction is a stateless bean, but shouldn't the entity manager stay alive within SMPC as long as the currentUser object is alive? If this isn't the case, what is an appropriate solution to this? Do I have to reload the user each time i like to access some information which are lazy loaded?

        • 1. Re: SFSB + @In leads to LazyInitalizationException
          coresystems_rit

          I expect this behaviour also in a different situation.


          I have a stateful session bean (employeeList) which displays a list of employees. In the ui there is a datatable which contains for each employee a link to a conversation scoped bean (employeeManager) to edit the employee. After editing the information on the employee the employeeManager fires an event which gets caught by the employeeList. This bean then reloads the datatable. During the reload the lazy initialization occrus, this time during the equals method of the model object:


          [LazyInitializationException] failed to lazily initialize a collection of role: model.Employee.assignedBranches, no session or session was closed



          Perhaps I have done some misconfiguration on the entity manager.


          components.xml


              <core:manager conversation-timeout="120000"
                            concurrent-request-timeout="500"
                            conversation-id-parameter="cid"/>
          
              <persistence:managed-persistence-context name="em" auto-create="true"
                                                       persistence-unit-jndi-name="java:/foo/emf" />
          
              <!-- Used by seam converters (e.g. <s:entityConverter />) -->
              <ui:jpa-entity-loader entity-manager="#{em}"/>
          
              <security:identity authenticate-method="#{authenticator.authenticate}"/>



          and the persistence.xml


              <persistence-unit name="foo">
                  <provider>org.hibernate.ejb.HibernatePersistence</provider>
                  <jta-data-source>java:/fooDS</jta-data-source>
                  <properties>
                      <property name="hibernate.hbm2ddl.auto" value="update"/>
                      <property name="hibernate.show_sql" value="true"/>
                      <property name="hibernate.format_sql" value="true" />
                      <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider"/>
                      <property name="hibernate.transaction.manager_lookup_class"
                                value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
                      <property name="jboss.entity.manager.factory.jndi.name" value="java:/foo/emf"/>
                  </properties>
              </persistence-unit>



          Did I miss something that this is working?


          Thanks for your help,


          Thierry



          • 2. Re: SFSB + @In leads to LazyInitalizationException
            javacoryd

            Your configuration is correct.


            The problem is the entityManger that you define in your components.xml file is mapped to a conversation and closes after you load in the currentUser on authentication.  Any lazy relationships won't load on subsequent conversations because the entity manager that backs this bean is closed.


            You will either need to:
            1) Load all relationships eagerly when you load the currentUser
            2) Re-read the currentUser with each conversation.


            I'm not sure if there is a way to create a session or application scoped entity manager.


            Cory.

            • 3. Re: SFSB + @In leads to LazyInitalizationException
              gonorrhea

              This is a very good scenario/question you have raised.  With JSR220, the extended persistence context is available with SFSB only.  The PC is available during the life of that particular SFSB (i.e. multiple business method calls until @Destroy method is invoked).


              I'm not sure if the same rule applies for the @In SMPC injection, but assuming hypothetically that this is the case, then for a SLSB like in your scenario, the SMPC is destroyed/unavailable after a SLSB's business method invocation is completed.


              Another solution to your problem is to use SFSB for your authenticator instead of SLSB but that doesn't really make sense to me b/c authenticator is typically a service bean which is modeled as SLSB or JavaBean and is not typically part of a client-specific use-case...