我有一个包含一组String的字段,用于保存和编辑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.servletConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62)[weld-core-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.ssolder.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.AbstractPersistentCollectionthrowLazyInitializationException(AbstractPersistentCollection.java:393)[hibernate-core-4.0.1.Final.jar:4.0.1.Final]在org.hibernate。collection.internal.AbstractPersistentCollectionthrowLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:385)[hibernate-core-4.0.1.Final.jar:4.0.1.Final]在org.hibernate。collection.internal.AbstractPersistentCollection.initialize(AbstractpersistentCollect.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.UUIInput.getConvertedValue(UIInput.java:1030)[jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]javax.faces.component.UUIInput.validate(UIInput.java:960)[jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]javax.faces.component.UUIInput.executeValidate(UIInput.java:1233)[jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]javax.faces.component.UUIInput.prrocessValidators(UIInput.java:698)[jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]javax.faces.component.UIForm.productValidators(UIForm.java:253)[jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]javax.faces.component.UIComponentBase.prrocessValidators(UIComponentBase.java:1214)[jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]javax.faces.component.UIWiewRoot.prrocessValidators(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.Impl.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>
谢谢你的帮助Nguyen
我找到了这个问题的解决方案,它已经在中公开了:@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>
Nguyen
问题与答案的差异:
***************
*** 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);
}