【问题标题】:ElementCollection: failed to lazily initialize a collection, no session or [duplicate]ElementCollection:无法延迟初始化集合,没有会话或[重复]
【发布时间】:2012-07-17 10:32:01
【问题描述】:

我有一个带有一组字符串的字段来保存和编辑 selectManyCheckbox 的值。我使用注释@ElementCollection,如中所述 http://docs.oracle.com/javaee/6/tutorial/doc/bnbqa.html 我可以第一次保存,但第二次保存时出现以下异常:

原因:javax.servlet.ServletException: 懒惰初始化失败 一个集合,没有会话或会话在 javax.faces.webapp.FacesServlet.service(FacesServlet.java:606) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final] 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.10.Final.jar:] 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.10.Final.jar:] 在 org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79) [primefaces-3.3.jar:] 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.10.Final.jar:] 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.10.Final.jar:] 在 org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62) [焊接核心-1.1.5.AS71.Final.jar:2012-02-10 15:31] 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.10.Final.jar:] 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.10.Final.jar:] 在 org.jboss.solder.servlet.exception.CatchExceptionFilter.doFilter(CatchExceptionFilter.java:65) [solder-impl-3.1.0.Final.jar:3.1.0.Final] ... 29 更多原因: org.hibernate.LazyInitializationException:延迟初始化失败 一个集合,没有会话或会话在 org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:393) [hibernate-core-4.0.1.Final.jar:4.0.1.Final] 在 org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:385) [hibernate-core-4.0.1.Final.jar:4.0.1.Final] 在 org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:378) [hibernate-core-4.0.1.Final.jar:4.0.1.Final] 在 org.hibernate.collection.internal.PersistentSet.add(PersistentSet.java:206) [hibernate-core-4.0.1.Final.jar:4.0.1.Final] 在 com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectManyValuesForModel(MenuRenderer.java:382) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT] 在 com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectManyValue(MenuRenderer.java:129) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT] 在 com.sun.faces.renderkit.html_basic.MenuRenderer.getConvertedValue(MenuRenderer.java:315) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT] 在 javax.faces.component.UIInput.getConvertedValue(UIInput.java:1030) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final] 在 javax.faces.component.UIInput.validate(UIInput.java:960) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final] 在 javax.faces.component.UIInput.executeValidate(UIInput.java:1233) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final] 在 javax.faces.component.UIInput.processValidators(UIInput.java:698) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final] 在 javax.faces.component.UIForm.processValidators(UIForm.java:253) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final] 在 javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final] 在 javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1172) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final] 在 com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT] 在 com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT] 在 com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT] 在 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] 在 javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final] ... 38 更多

我使用 JBOSS 7.1.0-Final、Hibernate 4.0.1.Final 和 JSF 2.0

以下是我的代码:

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>

以下是相关来源:

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>

感谢您的帮助 阮

【问题讨论】:

    标签: hibernate jsf uielementcollection


    【解决方案1】:

    我找到了这个问题的解决方案,已经在: @ElementCollection

    以下是我的解决方案:

    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>
    

    【讨论】:

    • dc360拒绝的编辑(应该是评论):你能不能也说明你改变了什么?您发布的链接虽然不错,但有几页长。
    【解决方案2】:

    问题与答案的区别:

    ***************
    *** 14,18 ****
            private Long id;
    
    !       @ElementCollection(fetch=FetchType.EAGER)
            private Set<String> textes;
    
    --- 14,18 ----
            private Long id;
    
    !       @ElementCollection
            private Set<String> textes;
    
    ***************
    *** 47,51 ****
          <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" />
    --- 47,51 ----
          <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" />
    ***************
    *** 70,75 ****
            private Test test;
    
            public String saveTest() {
    !           serviceBean.save(test);
                return "test";
            }
    --- 70,77 ----
            private Test test;
    
    +       private Set<String> selectedTextes;
    + 
            public String saveTest() {
    !           serviceBean.save(test, selectedTextes);
                return "test";
            }
    ***************
    *** 97,107 ****
            private EntityManager entityManager;
    
    !       public boolean save(Test test) {
                Test dbTest = findTestById(test.getId());
                if (dbTest == null) {
                    entityManager.persist(test);
                }
                else {
    !               entityManager.merge(test);
                }
    
    --- 99,115 ----
            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);
                }
    

    【讨论】:

      猜你喜欢
      • 2014-11-02
      • 1970-01-01
      • 2016-06-04
      • 2018-11-21
      • 2014-12-23
      • 2020-03-18
      • 2021-03-13
      • 1970-01-01
      • 2022-07-08
      相关资源
      最近更新 更多