7

Was ist der beste Weg, mehrere Chackboxen zu behandeln, wenn Sie eine JPA M: N Beziehung füllen ... zum Beispiel habe ich eine JPA-Entität Hardware und die Entität Connectivity.LazyInitializationException in selectManyCheckbox auf @ManyToMany (fetch = LAZY)

Hardware verfügt über einen Satz für die Konnektivität:

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

und einen Setter hat und wie diese 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; 
    } 

Ich verwende JSF2.2 und primefaces 5.3 in der gui ich habe:

Ich habe ein Problem mit Lazy-Ausnahme, auch wenn ich einen Aufruf erzwinge, laden Sie die Menge vor dem Rendern t er Ansicht:

hardware.getConnectivities().size(); 

Irgendwelche Suggestionen, wie man mit dieser Situation umgeht?

Ich verwende Omnifaces, um die Entity-Konvertierung zu machen.

Tnx zu BalusC Ich habe es geschafft, das Laden richtig zu machen, aber ich habe immer noch Probleme mit dem Speichern. Wenn ich das Kontrollkästchen und senden Sie das Formular wähle ich die faule Ausnahme bei der Umwandlung erhalten denke ich:

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) 

Antwort

8

Sie müssen um es zu holen, während innerhalb einer Transaktion (also innerhalb der Service-Methode) und nicht während draußen eine Transaktion (also z. B. in JSF verwaltete Bean-Init/Aktionsmethode), die somit eine LazyInitializationException werfen würde.

Also, Ihr Versuch

hardware.getConnectivities().size(); 

hat innerhalb einer Transaktion stattfinden kann. Erstellen Sie bei Bedarf eine neue Service-Methode, bei der Sie die Entität übergeben, die Sie zuvor in einer anderen Transaktion erhalten haben.

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

Eine Alternative wäre ein DTO für den Zweck zu schaffen, die es eifrig geholt hat.

Und dann die ausgewählten Elemente zu speichern, stellen Sie sicher, dass Sie geben die collectionType Attributauswahlkomponente auf einen Standard-Java-Typen explizit anstatt es impl spezifischen faul geladenen Typen wie org.hibernate.collection.internal.PersistentSet in Ihrem speziellen Fall eine JPA läßt selbstständig erkennen. JSF benötigt es, um die Sammlung zu instanziieren, bevor sie mit den ausgewählten Elementen gefüllt wird.

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

Siehe auch org.hibernate.LazyInitializationException at com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectManyValuesForModel.

+0

ich tue, dass im Inneren des PostConstruct der ViewScoped cdi Bohne – simonC

+0

Wie beantwortet, das ist nicht innerhalb einer Transaktion. – BalusC

+0

Ok und wenn ich versuche zu speichern, bekomme ich auch eine faule Ausnahme ... Was ist der richtige Weg, um in diesen Situationen zu retten? – simonC

1

ich es beheben nur durch specifie

<f:attribute name="collectionType" value="java.util.LinkedHashSet" /> 
+0

Dann waren Sie bereits in einer Transaktion, wie in der anderen Antwort erwähnt – Kukeltje