2015-05-07 28 views
7

Qual è il modo migliore per gestire più chackbox quando non è necessario riempire una relazione M: N JPA ... ad esempio, ho un'entità JPA Hardware e l'entità Connettività.LazyInitializationException in selectManyCheckbox su @ManyToMany (fetch = LAZY)

Hardware ha un set per la connettività:

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

e ha un setter e getter in questo modo:

@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; 
    } 

sto usando JSF2.2 e primefaces 5.3 nella GUI che ho:

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

Ho un problema con l'eccezione lazy anche se faccio una chiamata per forzare il carico del set prima di renderizzare egli visualizza:

Eventuali suggerimenti su come gestire questa situazione?

Sto usando omnifaces per effettuare la conversione dell'entità.

Da tnx a BalusC sono riuscito a eseguire il caricamento corretto ma ho ancora problemi con il salvataggio di wuth. Quando seleziono la casella di controllo e inviare il modulo ottengo l'eccezione pigro nella conversione penso:

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) 

risposta

8

dovrai scaricare, mentre all'interno di una transazione (in tal modo, all'interno del metodo del servizio), e non mentre fuori una transazione (quindi, ad esempio, all'interno del metodo init/action bean gestito da JSF), che quindi genererebbe uno LazyInitializationException.

Così, il vostro tentativo

hardware.getConnectivities().size(); 

deve avvenire all'interno di una transazione. Creare se necessario un nuovo metodo di servizio per lo scopo in cui si passa l'entità che è stata ottenuta prima in un'altra transazione.

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

Un'alternativa sarebbe quella di creare un DTO per lo scopo che ha avidamente recuperato.

E poi per salvare gli elementi selezionati, assicurarsi che si specifica in modo esplicito l'attributo del componente selezione collectionType a un tipo Java standard piuttosto che lasciare che l'individuazione automatica di un JPA impl specifico tipo di carico pigri come org.hibernate.collection.internal.PersistentSet nel vostro caso specifico. JSF ne ha bisogno per istanziare la raccolta prima di riempirla con gli elementi selezionati.

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

Vedere anche org.hibernate.LazyInitializationException at com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectManyValuesForModel.

+0

sto facendo che all'interno della PostConstruct del cdi fagiolo ViewScoped – simonC

+0

come risposta, che non è all'interno di una transazione. – BalusC

+0

Ok e quando provo a salvare ricevo anche un'eccezione pigra ... qual è il modo corretto di gestire il salvataggio in queste situazioni? – simonC

1

posso risolvere il problema solo da specifie

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

Allora eri già in una transazione come menzionato nell'altra risposta – Kukeltje