@ManyToMany的selectManyCheckbox中的LazyInitializationException(fetch = LAZY) [英] LazyInitializationException in selectManyCheckbox on @ManyToMany(fetch=LAZY)

查看:97
本文介绍了@ManyToMany的selectManyCheckbox中的LazyInitializationException(fetch = LAZY)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当您需要填写JPA M:N关系时,处理多个hackbox的最佳方法是什么……例如,我有一个JPA实体硬件和实体连接性.

What is the best way to handle multiple chackboxes when you nead to fill a JPA M:N relation ... for example I have an JPA entity Hardware and the entity Connectivity.

硬件具有一套连通性:

private Set<Connectivity> connectivities = new HashSet<Connectivity>(0);

并具有如下的setter和getter:

and has a setter and getter like this :

@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:

I'm using JSF2.2 and primefaces 5.3 in the gui I have:

<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>

即使在渲染视图之前进行了强制加载集合的调用,我也有延迟异常的问题:

I have problem with lazy exception even if I make a call to force load the set before rendering the view:

hardware.getConnectivities().size();

有关如何处理这种情况的任何建议?

Any suggiestions on how to handle this situation?

我正在使用全能型进行实体转换.

I'm using omnifaces to make the entity conversion.

Tnx到BalusC我已经设法正确地进行了加载,但是在保存方面仍然存在问题.当我选中该复选框并提交表单时,我在转换中得到了懒惰的异常,我认为:

Tnx to BalusC I have managed to do the loading right but I still have problem wuth saving. When I select the checkbox and submit the form I get the lazy exception in conversion I think:

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$000(ServletInitialHandler.java:76)
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:166)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:197)
    at io.undertow.server.HttpServerExchange$1.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)

推荐答案

您需要在事务内部(因此,在service方法内部)获取数据,而在事务外部(因此,在服务方法内部)获取不是 ,例如JSF托管的bean init/action方法),因此将抛出LazyInitializationException.

You need to fetch it while inside a transaction (thus, inside the service method), and not while outside a transaction (thus, inside e.g. JSF managed bean init/action method), that would thus throw a LazyInitializationException.

所以,你的尝试

hardware.getConnectivities().size();

必须在交易内部进行.如有必要,请创建新的服务方法,以使您传递之前在另一笔交易中获得的实体.

has to take place inside a transaction. Create if necessary a new service method for the purpose whereby you pass the entity which was obtained before in another transaction.

hardwareService.fetchConnectivities(hardware);

public void fetchConnectivities(Hardware hardware) {
    hardware.setConnectivities(em.merge(hardware).getConnectivities()); // Becomes managed.
    hardware.getConnectivities().size(); // Triggers lazy initialization.
}

一种替代方法是为急切获取的目的创建一个DTO.

An alternative would be to create a DTO for the purpose which has it eagerly fetched.

然后保存选定的项目,请确保您将选择组件的collectionType属性显式指定为标准Java类型,而不是让它自动发现JPA隐式特定于延迟加载的类型,例如您的特定情况下的org.hibernate.collection.internal.PersistentSet . JSF需要它以便实例化集合,然后再用选定的项目填充它.

And then to save the selected items, make sure that you explicitly specify the selection component's collectionType attribute to a standard Java type rather than letting it autodiscover a JPA impl specific lazy loaded type such as org.hibernate.collection.internal.PersistentSet in your specific case. JSF needs it in order to instantiate the collection before filling it with the selected items.

<p:selectManyCheckbox ... collectionType="java.util.LinkedHashSet">

另请参见 org.hibernate.LazyInitializationException,网址为com .sun.faces.renderkit.html_basic.MenuRenderer.convertSelectManyValuesForModel .

这篇关于@ManyToMany的selectManyCheckbox中的LazyInitializationException(fetch = LAZY)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆