4 Replies Latest reply: Jul 19, 2012 5:05 AM by 949962 RSS

    ElementCollection: failed to lazily initialize a collection, no session or

    949962
      Hi,

      I have a field with a set of String to save and edit the value of selectManyCheckbox. I use the annotation @ElementCollection as described in
      [http://docs.oracle.com/javaee/6/tutorial/doc/bnbqa.html |http://docs.oracle.com/javaee/6/tutorial/doc/bnbqa.html]
      I can save at the first time but by editing I got the following exceptions:

      Caused by: javax.servlet.ServletException: failed to lazily initialize a collection, no session or session was closed
           at javax.faces.webapp.FacesServlet.service(FacesServlet.java:606) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.10.Final.jar:]
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.10.Final.jar:]
           at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79) [primefaces-3.3.jar:]
           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.10.Final.jar:]
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.10.Final.jar:]
           at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.10.Final.jar:]
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.10.Final.jar:]
           at org.jboss.solder.servlet.exception.CatchExceptionFilter.doFilter(CatchExceptionFilter.java:65) [solder-impl-3.1.0.Final.jar:3.1.0.Final]
           ... 29 more
      Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection, no session or session was closed
           at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:393) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
           at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:385) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
           at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:378) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
           at org.hibernate.collection.internal.PersistentSet.add(PersistentSet.java:206) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
           at com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectManyValuesForModel(MenuRenderer.java:382) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
           at com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectManyValue(MenuRenderer.java:129) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
           at com.sun.faces.renderkit.html_basic.MenuRenderer.getConvertedValue(MenuRenderer.java:315) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
           at javax.faces.component.UIInput.getConvertedValue(UIInput.java:1030) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
           at javax.faces.component.UIInput.validate(UIInput.java:960) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
           at javax.faces.component.UIInput.executeValidate(UIInput.java:1233) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
           at javax.faces.component.UIInput.processValidators(UIInput.java:698) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
           at javax.faces.component.UIForm.processValidators(UIForm.java:253) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
           at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
           at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1172) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
           at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
           at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
           at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
           at org.apache.myfaces.extensions.cdi.jsf2.impl.listener.phase.CodiLifecycleWrapper.execute(CodiLifecycleWrapper.java:95) [myfaces-extcdi-jsf20-module-impl-1.0.5.jar:1.0.5]
           at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
           ... 38 more


      I use JBOSS 7.1.0-Final, Hibernate 4.0.1.Final and JSF 2.0

      Following are my codes:

      Test.java_

      @Entity
      @Table(name = "TEST")
      @NamedQueries({
           @NamedQuery(name = Test.FIND_BY_ID, query = "select test from Test test where test.id = :id")
      })
      public class Test implements Serializable {

           private static final long serialVersionUID = -7294677843656741933L;

           public static final String FIND_BY_ID = "test.by.id";
           
           @Id
           @GeneratedValue(strategy = GenerationType.AUTO)
           private Long id;
           
           *@ElementCollection(fetch=FetchType.EAGER)*
           private Set<String> textes;

           
           public Test() {
           }

           public Long getId() {
                return id;
           }

           public void setId(Long id) {
                this.id = id;
           }

           public Set<String> getTextes() {
                return textes;
           }

           public void setTextes(Set<String> textes) {
                this.textes = textes;
           }
      }


      test.xhtml_

      <?xml version='1.0' encoding='UTF-8' ?>
      <!DOCTYPE html>
      <html xmlns="http://www.w3.org/1999/xhtml"
           xmlns:ui="http://java.sun.com/jsf/facelets"
           xmlns:h="http://java.sun.com/jsf/html"
           xmlns:f="http://java.sun.com/jsf/core"
           xmlns:c="http://java.sun.com/jsp/jstl/core">

      <body>
           <h:form id="form">
                *<h:selectManyCheckbox value="#{formBean.test.textes}">*
                     <f:selectItem itemLabel="Option 1" itemValue="Option 1" />
      <f:selectItem itemLabel="Option 2" itemValue="Option 2" />
      <f:selectItem itemLabel="Option 3" itemValue="Option 3" />
                </h:selectManyCheckbox>

                <h:commandButton value="Save" action="#{formBean.saveTest}" />
           </h:form>
      </body>
      </html>


      Following are the related sources:

      FormBean.java_

      @Named
      @SessionScoped
      public class FormBean implements Serializable {

           private static final long serialVersionUID = 6484233109393875203L;
           
           @EJB
           private ServiceBean serviceBean;
           
           private Test test;

           public String saveTest() {
                serviceBean.save(test);
                return "test";
           }
           
           public String createTest() {
                test = new Test();
                return "test";
           }
           
           public Test getTest() {
                return test;
           }

           public void setTest(Test test) {
                this.test = test;
           }
           
      }


      ServiceBean.java_

      @Stateless
      @LocalBean
      public class ServiceBean {

           @PersistenceContext
           private EntityManager entityManager;

           public boolean save(Test test) {
                Test dbTest = findTestById(test.getId());
                if (dbTest == null) {
                     entityManager.persist(test);
                }
                else {
                     entityManager.merge(test);
                }
                
                return true;
           }
           
           public Test findTestById(Long id) {
                if (id == null)
                     return null;

                TypedQuery<Test> query = entityManager.createNamedQuery(Test.FIND_BY_ID, Test.class);
                query.setParameter("id", id);
                List<Test> results = query.getResultList();

                if (results.isEmpty())
                     return null;

                return results.get(0);
           }
      }


      test_index.xhtml

      <?xml version='1.0' encoding='UTF-8' ?>
      <!DOCTYPE html>
      <html xmlns="http://www.w3.org/1999/xhtml"
           xmlns:ui="http://java.sun.com/jsf/facelets"
           xmlns:h="http://java.sun.com/jsf/html"
           xmlns:f="http://java.sun.com/jsf/core"
           xmlns:c="http://java.sun.com/jsp/jstl/core">

      <body>
           <h:form>
                <h:commandLink value="Test" action="#{formBean.createTest()}" />
           </h:form>
      </body>
      </html>

      Thanks for helps
      Nguyen
        • 1. Re: ElementCollection: failed to lazily initialize a collection, no session or
          gimbal2
          Seems like Hibernate is not listening to your EAGER loading flag and is lazily initializing the collection anyway. Seems like buggy behavior, but I'm only guessing there. Perhaps you should ask around in the Hibernate forum (on the hibernate website) about this issue.

          EDIT:

          assuming this is not your own failure due to forgetting to recompile/redeploy before running of course.
          • 2. Re: ElementCollection: failed to lazily initialize a collection, no session or
            949962
            Thanks for your answer. The problem is not caused by recompiling/redeploying.

            My question is also found in the Hibernate forum:

            [https://forum.hibernate.org/viewtopic.php?f=1&t=1017170]
            • 3. Re: ElementCollection: failed to lazily initialize a collection, no session or
              gimbal2
              user11365718 wrote:
              Thanks for your answer. The problem is not caused by recompiling/redeploying.
              I'm not saying that - I'm saying it may be SOLVED by recompiling/redeploying. You wouldn't be the first to make some changes and then either forget to or not properly redeploy to see the actual change in the running environment.

              But now that the question exists in the Hibernate forum, I'm sure you'll get an answer. I'm keeping a curious eye on it myself.
              • 4. Re: ElementCollection: failed to lazily initialize a collection, no session or
                949962
                I found the solution for this problem, which is already publiced in:
                [http://en.wikibooks.org/wiki/Java_Persistence/ElementCollection]

                Following is my solution:

                Test.java

                @Entity
                @Table(name = "TEST")
                @NamedQueries({
                     @NamedQuery(name = Test.FIND_BY_ID, query = "select test from Test test where test.id = :id")
                })
                public class Test implements Serializable {

                     private static final long serialVersionUID = -7294677843656741933L;

                     public static final String FIND_BY_ID = "test.by.id";
                     
                     @Id
                     @GeneratedValue(strategy = GenerationType.AUTO)
                     private Long id;
                     
                     @ElementCollection
                     private Set<String> textes;
                     
                     public Test() {
                     }

                     public Long getId() {
                          return id;
                     }

                     public void setId(Long id) {
                          this.id = id;
                     }

                     public Set<String> getTextes() {
                          return textes;
                     }

                     public void setTextes(Set<String> textes) {
                          this.textes = textes;
                     }
                }

                test.xhtml

                <?xml version='1.0' encoding='UTF-8' ?>
                <!DOCTYPE html>
                <html xmlns="http://www.w3.org/1999/xhtml"
                     xmlns:ui="http://java.sun.com/jsf/facelets"
                     xmlns:h="http://java.sun.com/jsf/html"
                     xmlns:f="http://java.sun.com/jsf/core"
                     xmlns:c="http://java.sun.com/jsp/jstl/core">

                <body>
                     <h:form id="form">
                          <h:selectManyCheckbox value="#{formBean.selectedTextes}">
                               <f:selectItem itemLabel="Option 1" itemValue="Option 1" />
                <f:selectItem itemLabel="Option 2" itemValue="Option 2" />
                <f:selectItem itemLabel="Option 3" itemValue="Option 3" />
                          </h:selectManyCheckbox>

                          <h:commandButton value="Save" action="#{formBean.saveTest}" />
                     </h:form>
                </body>
                </html>


                FormBean.java

                @Named
                @SessionScoped
                public class FormBean implements Serializable {

                     private static final long serialVersionUID = 6484233109393875203L;
                     
                     @EJB
                     private ServiceBean serviceBean;
                     
                     private Test test;

                     private Set<String> selectedTextes;

                     public String saveTest() {
                          serviceBean.save(test, selectedTextes);
                          return "test";
                     }
                     
                     public String createTest() {
                          test = new Test();
                          return "test";
                     }
                     
                     // getters and setters
                }

                ServiceBean.java

                @Stateless
                @LocalBean
                public class ServiceBean {

                     @PersistenceContext
                     private EntityManager entityManager;

                     public boolean save(Test test, Set<String> selectedTextes) {
                          Test dbTest = findTestById(test.getId());
                          if (dbTest == null) {
                               if (selectedTextes != null) {
                                    test.setTextes(selectedTextes);
                               }
                               entityManager.persist(test);
                          }
                          else {
                               if (selectedTextes != null) {
                                    dbTest.setTextes(selectedTextes);
                               }
                               entityManager.merge(dbTest);
                          }
                          
                          return true;
                     }
                     
                     public Test findTestById(Long id) {
                          if (id == null)
                               return null;

                          TypedQuery<Test> query = entityManager.createNamedQuery(Test.FIND_BY_ID, Test.class);
                          query.setParameter("id", id);
                          List<Test> results = query.getResultList();

                          if (results.isEmpty())
                               return null;

                          return results.get(0);
                     }
                }


                test_index.xhtml

                <?xml version='1.0' encoding='UTF-8' ?>
                <!DOCTYPE html>
                <html xmlns="http://www.w3.org/1999/xhtml"
                     xmlns:ui="http://java.sun.com/jsf/facelets"
                     xmlns:h="http://java.sun.com/jsf/html"
                     xmlns:f="http://java.sun.com/jsf/core"
                     xmlns:c="http://java.sun.com/jsp/jstl/core">

                <body>
                     <h:form>
                          <h:commandLink value="Test" action="#{formBean.createTest()}" />
                     </h:form>
                </body>
                </html>

                Nguyen