7

Jaki jest najlepszy sposób na obsługę wielu chackboxów, gdy nie chcesz wypełnić relacji JPA M: N ... na przykład mam obiekt WZP Hardware i encję Łączność.LazyInitializationException w selectManyCheckbox na @ManyToMany (fetch = LAZY)

Sprzęt posiada zestaw do łączności:

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

i ma setter i getter tak:

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

Używam JSF2.2 i primefaces 5,3 w GUI mam:

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

mam problem z leniwym wyjątku, nawet jeśli robię to wezwanie do wymuszenia załadować zestaw przed renderowania t on view:

hardware.getConnectivities().size(); 

Jakieś sugestie, jak poradzić sobie z tą sytuacją?

Używam omnifaces, aby dokonać konwersji encji.

Tnx do BalusC Udało mi się zrobić ładowanie, ale nadal mam problem z zapisaniem. Po zaznaczeniu pola wyboru i złożyć formularz I dostać leniwy wyjątek konwersji myślę:

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) 

Odpowiedz

8

Trzeba go sprowadzić natomiast wewnątrz transakcji (czyli wewnątrz metody service) oraz nie podczas gdy na zewnątrz transakcja (czyli w środku, np. JSF managed bean init/action method), która w ten sposób wygenerowałaby LazyInitializationException.

Więc twoja próba

hardware.getConnectivities().size(); 

musi odbywać się wewnątrz transakcji. Utwórz w razie potrzeby nową metodę usługi w celu przekazania podmiotowi uzyskanemu wcześniej w innej transakcji.

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

Alternatywą byłoby stworzyć dto do celu, który ma to chętnie naciągane.

A potem, aby zapisać wybrane elementy, upewnij się, że jawnie określić składnika konkursowej collectionType atrybut do standardowego typu Java, zamiast pozwolić jej automatycznie przeszuka do WZP IMPL specyficzny typ leniwy załadowany takich jak org.hibernate.collection.internal.PersistentSet w Twoim konkretnym przypadku. JSF potrzebuje tego, aby utworzyć kolekcję przed jej wypełnieniem wybranymi elementami.

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

Zobacz także org.hibernate.LazyInitializationException at com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectManyValuesForModel.

+0

robie że wewnątrz PostConstruct z CDI fasoli ViewScoped – simonC

+0

Jak odpowiedział, że nie znajduje się wewnątrz transakcji. – BalusC

+0

Ok i kiedy próbuję zapisać, również dostaję leniwy wyjątek ... jaki jest właściwy sposób na zachowanie w takich sytuacjach? – simonC

1

to naprawić tylko przez specifie

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

Następnie byłeś już w transakcji, o czym wspomniano w drugiej odpowiedzi – Kukeltje