@ManyToMany(fetch=LAZY) 上的 selectManyCheckbox 中的 LazyInitializationException
LazyInitializationException in selectManyCheckbox on @ManyToMany(fetch=LAZY)
当您需要填充 JPA M:N 关系时,处理多个复选框的最佳方法是什么...例如,我有一个 JPA 实体硬件和实体连接。
硬件有一组连接:
private Set<Connectivity> connectivities = new HashSet<Connectivity>(0);
并且有一个 setter 和 getter 像这样:
@ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.REFRESH }, mappedBy = "hwProviders")
public Set<Connectivity> getConnectivities() {
return this.connectivities;
}
public void setConnectivities(Set<Connectivity> connectivities) {
this.connectivities = connectivities;
}
我在 gui 中使用 JSF2.2 和 primefaces 5.3:
<p:selectManyCheckbox id="connectivity" value="#{hardware.connectivities}" converter="omnifaces.SelectItemsConverter" layout="pageDirection">
<f:selectItems value="#{connectivityes}" var="connect" itemValue="#{connect}" itemLabel="#{connect.name}"/>
</p:selectManyCheckbox>
即使我在渲染视图之前调用强制加载集,我仍然遇到延迟异常问题:
hardware.getConnectivities().size();
关于如何处理这种情况有什么建议吗?
我正在使用 omnifaces 进行实体转换。
Tnx to BalusC 我已经设法正确加载,但我仍然有保存问题。当我 select 复选框并提交表单时,我在转换中遇到了惰性异常,我认为:
16:34:50,538 SEVERE [javax.enterprise.resource.webcontainer.jsf.context] (default task-12) org.hibernate.LazyInitializationException: failed to lazily initialize a collection, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:554)
at org.hibernate.collection.internal.PersistentSet.add(PersistentSet.java:202)
at com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectManyValuesForModel(MenuRenderer.java:381)
at com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectManyValue(MenuRenderer.java:128)
at com.sun.faces.renderkit.html_basic.MenuRenderer.getConvertedValue(MenuRenderer.java:314)
at org.primefaces.component.selectmanycheckbox.SelectManyCheckboxRenderer.getConvertedValue(SelectManyCheckboxRenderer.java:39)
at javax.faces.component.UIInput.getConvertedValue(UIInput.java:1045)
at javax.faces.component.UIInput.validate(UIInput.java:975)
at javax.faces.component.UIInput.executeValidate(UIInput.java:1248)
at javax.faces.component.UIInput.processValidators(UIInput.java:712)
at javax.faces.component.UIForm.processValidators(UIForm.java:253)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1260)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1260)
at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1195)
at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:130)
at si.arctur.filter.SessionFilter.doFilter(SessionFilter.java:76)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:56)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:63)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70)
at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:261)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:247)
at io.undertow.servlet.handlers.ServletInitialHandler.access[=14=]0(ServletInitialHandler.java:76)
at io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:166)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:197)
at io.undertow.server.HttpServerExchange.run(HttpServerExchange.java:759)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
您需要在事务内部(因此,在服务方法内部)获取它,而不是在事务外部(因此,在例如 JSF 托管 bean 内部)init/action 方法),因此会抛出 LazyInitializationException
.
所以,你的尝试
hardware.getConnectivities().size();
必须在交易中发生。如有必要,创建一个新的服务方法,以便您传递之前在另一笔交易中获得的实体。
hardwareService.fetchConnectivities(hardware);
public void fetchConnectivities(Hardware hardware) {
hardware.setConnectivities(em.merge(hardware).getConnectivities()); // Becomes managed.
hardware.getConnectivities().size(); // Triggers lazy initialization.
}
另一种方法是创建一个 DTO 用于急切获取它的目的。
然后要保存所选项目,请确保将选择组件的 collectionType
属性明确指定为标准 Java 类型,而不是让它自动发现 JPA impl 特定的延迟加载类型,例如作为 org.hibernate.collection.internal.PersistentSet
在您的具体情况下。 JSF 需要它以便在用所选项目填充集合之前实例化集合。
<p:selectManyCheckbox ... collectionType="java.util.LinkedHashSet">
另见 org.hibernate.LazyInitializationException at com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectManyValuesForModel。
我只通过指定修复它
<f:attribute name="collectionType" value="java.util.LinkedHashSet" />
当您需要填充 JPA M:N 关系时,处理多个复选框的最佳方法是什么...例如,我有一个 JPA 实体硬件和实体连接。
硬件有一组连接:
private Set<Connectivity> connectivities = new HashSet<Connectivity>(0);
并且有一个 setter 和 getter 像这样:
@ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.REFRESH }, mappedBy = "hwProviders")
public Set<Connectivity> getConnectivities() {
return this.connectivities;
}
public void setConnectivities(Set<Connectivity> connectivities) {
this.connectivities = connectivities;
}
我在 gui 中使用 JSF2.2 和 primefaces 5.3:
<p:selectManyCheckbox id="connectivity" value="#{hardware.connectivities}" converter="omnifaces.SelectItemsConverter" layout="pageDirection">
<f:selectItems value="#{connectivityes}" var="connect" itemValue="#{connect}" itemLabel="#{connect.name}"/>
</p:selectManyCheckbox>
即使我在渲染视图之前调用强制加载集,我仍然遇到延迟异常问题:
hardware.getConnectivities().size();
关于如何处理这种情况有什么建议吗?
我正在使用 omnifaces 进行实体转换。
Tnx to BalusC 我已经设法正确加载,但我仍然有保存问题。当我 select 复选框并提交表单时,我在转换中遇到了惰性异常,我认为:
16:34:50,538 SEVERE [javax.enterprise.resource.webcontainer.jsf.context] (default task-12) org.hibernate.LazyInitializationException: failed to lazily initialize a collection, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:554)
at org.hibernate.collection.internal.PersistentSet.add(PersistentSet.java:202)
at com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectManyValuesForModel(MenuRenderer.java:381)
at com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectManyValue(MenuRenderer.java:128)
at com.sun.faces.renderkit.html_basic.MenuRenderer.getConvertedValue(MenuRenderer.java:314)
at org.primefaces.component.selectmanycheckbox.SelectManyCheckboxRenderer.getConvertedValue(SelectManyCheckboxRenderer.java:39)
at javax.faces.component.UIInput.getConvertedValue(UIInput.java:1045)
at javax.faces.component.UIInput.validate(UIInput.java:975)
at javax.faces.component.UIInput.executeValidate(UIInput.java:1248)
at javax.faces.component.UIInput.processValidators(UIInput.java:712)
at javax.faces.component.UIForm.processValidators(UIForm.java:253)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1260)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1260)
at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1195)
at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:130)
at si.arctur.filter.SessionFilter.doFilter(SessionFilter.java:76)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:56)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:63)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70)
at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:261)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:247)
at io.undertow.servlet.handlers.ServletInitialHandler.access[=14=]0(ServletInitialHandler.java:76)
at io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:166)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:197)
at io.undertow.server.HttpServerExchange.run(HttpServerExchange.java:759)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
您需要在事务内部(因此,在服务方法内部)获取它,而不是在事务外部(因此,在例如 JSF 托管 bean 内部)init/action 方法),因此会抛出 LazyInitializationException
.
所以,你的尝试
hardware.getConnectivities().size();
必须在交易中发生。如有必要,创建一个新的服务方法,以便您传递之前在另一笔交易中获得的实体。
hardwareService.fetchConnectivities(hardware);
public void fetchConnectivities(Hardware hardware) {
hardware.setConnectivities(em.merge(hardware).getConnectivities()); // Becomes managed.
hardware.getConnectivities().size(); // Triggers lazy initialization.
}
另一种方法是创建一个 DTO 用于急切获取它的目的。
然后要保存所选项目,请确保将选择组件的 collectionType
属性明确指定为标准 Java 类型,而不是让它自动发现 JPA impl 特定的延迟加载类型,例如作为 org.hibernate.collection.internal.PersistentSet
在您的具体情况下。 JSF 需要它以便在用所选项目填充集合之前实例化集合。
<p:selectManyCheckbox ... collectionType="java.util.LinkedHashSet">
另见 org.hibernate.LazyInitializationException at com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectManyValuesForModel。
我只通过指定修复它
<f:attribute name="collectionType" value="java.util.LinkedHashSet" />