LazyInitializationException with Managed CDI Bean and Bean State Session

I have a managed CDI Bean (a Bean annotated with @Named that is used in JSF) that has a nested Bean session. This Bean session is like a service, it has an entity manager (annotated with @PersistenceContext (type = PersistenceContextType.EXTENDED)) and exposes arrival methods for managing some objects. These objects are located on a managed bean, which is a ConversationScoped. Then, the JSF calls the managed bean method, and the managed bean calls some "service" method (session with bean state). I don't know if this is the best design, but it works well. But there is an Entity that has some collections that need to be obtained with LAZY. And the first time I open the page, it works well, but when I try to press any button or do some action, I have a LazyInitializationException. Does anyone have a clue? I don’t know if something is wrong. I set the Bean session to be stateful, and the persistence context is expanded. This Bean session is injected into a managed bean that has entities. Why does this throw this exception? How can I close the object manager?

This is the code of an entity that is in trouble:

@Entity public class ParametrosVingentes implements Serializable { public static final String ID = "settings"; private static final long serialVersionUID = 1L; @Id private String id; @OneToOne private ValorHora valorHora; @OneToMany @JoinTable( name="BuscaSistecVingentes", joinColumns = @JoinColumn( name="parametros_vingentes_fk"), inverseJoinColumns = @JoinColumn( name="agendamento_fk") ) private List<AgendamentoBuscaSistec> agendamentosBuscaSistec; @OneToMany @JoinTable( name="ExportacaoZeusVingentes", joinColumns = @JoinColumn( name="parametros_vingentes_fk"), inverseJoinColumns = @JoinColumn( name="agendamento_fk") ) private List<AgendamentoExportacaoZeus> agendamentosExportacaoZeus; @OneToMany @JoinTable( name="ImportacaoZeusVingentes", joinColumns = @JoinColumn( name="parametros_vingentes_fk"), inverseJoinColumns = @JoinColumn( name="agendamento_fk") ) private List<AgendamentoImportacaoZeus> agendamentosImportacaoZeus; public ParametrosVingentes() { this.id = ID; } // getters and setters... 

This is a Bean state session:

 @Stateful @LocalBean @TransactionAttribute(TransactionAttributeType.REQUIRED) public class ParametrosService implements Serializable { @PersistenceContext(type= PersistenceContextType.EXTENDED) private EntityManager entityManager; public void cadastrar(ValorHora valorHora){ ValorHoraDao valorHoraDao = new ValorHoraDao(entityManager); valorHoraDao.salvar(valorHora); } @TransactionAttribute(TransactionAttributeType.SUPPORTS) public List<ValorHora> listarValorHora(){ ValorHoraDao valorHoraDao = new ValorHoraDao(entityManager); return valorHoraDao.getAll(); } public boolean excluir(ValorHora valorHora){ if(valorHora.getRemessas() != null && !valorHora.getRemessas().isEmpty()){ return false; } ValorHoraDao valorHoraDao = new ValorHoraDao(entityManager); valorHoraDao.remover(valorHora); return true; } public void cadastrar(AgendamentoBuscaSistec agendamentoBuscaSistec){ AgendamentoBuscaSistecDao agendamentoBuscaSistecDao = new AgendamentoBuscaSistecDao(entityManager); agendamentoBuscaSistecDao.salvar(agendamentoBuscaSistec); } @TransactionAttribute(TransactionAttributeType.SUPPORTS) public List<AgendamentoBuscaSistec> listarAgendamentoBuscaSistec(){ AgendamentoBuscaSistecDao agendamentoBuscaSistecDao = new AgendamentoBuscaSistecDao(entityManager); return agendamentoBuscaSistecDao.getAgendamentos(); } public void excluir(AgendamentoBuscaSistec agendamentoBuscaSistec){ AgendamentoBuscaSistecDao agendamentoBuscaSistecDao = new AgendamentoBuscaSistecDao(entityManager); agendamentoBuscaSistecDao.remover(agendamentoBuscaSistec); } public void cadastrar(AgendamentoExportacaoZeus agendamentoExportacaoZeus){ AgendamentoExportacaoZeusDao agendamentoExportacaoZeusDao = new AgendamentoExportacaoZeusDao(entityManager); agendamentoExportacaoZeusDao.salvar(agendamentoExportacaoZeus); } @TransactionAttribute(TransactionAttributeType.SUPPORTS) public List<AgendamentoExportacaoZeus> listarAgendamentoExportacaoZeus(){ AgendamentoExportacaoZeusDao agendamentoExportacaoZeusDao = new AgendamentoExportacaoZeusDao(entityManager); return agendamentoExportacaoZeusDao.getAgendamentos(); } public void excluir(AgendamentoExportacaoZeus agendamentoExportacaoZeus){ AgendamentoExportacaoZeusDao agendamentoExportacaoZeusDao = new AgendamentoExportacaoZeusDao(entityManager); agendamentoExportacaoZeusDao.remover(agendamentoExportacaoZeus); } public void cadastrar(AgendamentoImportacaoZeus agendamentoImportacaoZeus){ AgendamentoImportacaoZeusDao agendamentoImportacaoZeusDao = new AgendamentoImportacaoZeusDao(entityManager); agendamentoImportacaoZeusDao.salvar(agendamentoImportacaoZeus); } @TransactionAttribute(TransactionAttributeType.SUPPORTS) public List<AgendamentoImportacaoZeus> listarAgendamentoImportacaoZeus(){ AgendamentoImportacaoZeusDao agendamentoImportacaoZeusDao = new AgendamentoImportacaoZeusDao(entityManager); return agendamentoImportacaoZeusDao.getAgendamentos(); } public void excluir(AgendamentoImportacaoZeus agendamentoImportacaoZeus){ AgendamentoImportacaoZeusDao agendamentoImportacaoZeusDao = new AgendamentoImportacaoZeusDao(entityManager); agendamentoImportacaoZeusDao.remover(agendamentoImportacaoZeus); } @TransactionAttribute(TransactionAttributeType.SUPPORTS) public ParametrosVingentes getParametrosVingentes(){ return ParametrosUtil.getParametrosVingentes(entityManager); } public void atualizarParametrosVingentes(ParametrosVingentes parametrosVingentes){ ParametrosVingentesDao parametrosVingentesDao = new ParametrosVingentesDao(entityManager); parametrosVingentes = parametrosVingentesDao.atualizar(parametrosVingentes); } } 

A managed Bean calls the getParametrosVingentes () method of a bean session. I use the static ParametrosUtil method to get (if it exists) or create (if it does not exist) the ParametrosVingentes parameter. This is because it is necessary that there is only one ParametrosVingentes in the application. This is a Bean that has parameters used by other components. This is the ParametrosUtil code:

 public class ParametrosUtil { public static synchronized ParametrosVingentes getParametrosVingentes(EntityManager entityManager){ ParametrosVingentesDao parametrosVingentesDao = new ParametrosVingentesDao(entityManager); ParametrosVingentes parametrosVingentes = parametrosVingentesDao.buscar(ParametrosVingentes.ID); if(parametrosVingentes == null){ parametrosVingentes = new ParametrosVingentes(); } return parametrosVingentes; } public static synchronized ParametrosVingentes atualizarParametrosVingentes(ParametrosVingentes parametrosVingentes, EntityManager entityManager){ ParametrosVingentesDao parametrosVingentesDao = new ParametrosVingentesDao(entityManager); return parametrosVingentesDao.atualizar(parametrosVingentes); } } 

This is a managed bean:

 @Named(value = "parametros") @ConversationScoped public class Parametros implements Serializable { public static final int VISAO_PARAMETROS_VINGENTES = 1; public static final int VISAO_VALOR_HORA = 2; public static final int VISAO_AGENDAMENTO_SISTEC = 3; public static final int VISAO_AGENDAMENTO_EXPORTACAO_ZEUS = 4; public static final int VISAO_AGENDAMENTO_IMPORTACAO_ZEUS = 5; private int visaoAtual; @EJB private ParametrosService parametrosService; @Inject private Conversation conversation; private ValorHora valorHora; private AgendamentoBuscaSistec agendamentoBuscaSistec; private AgendamentoExportacaoZeus agendamentoExportacaoZeus; private AgendamentoImportacaoZeus agendamentoImportacaoZeus; private List<ValorHora> listaValorHora; private boolean listaValorHoraModificada; private List<AgendamentoBuscaSistec> listaAgendamentoBuscaSistec; private boolean listaAgendamentoBuscaSistecModificada; private List<AgendamentoExportacaoZeus> listaAgendamentoExportacaoZeus; private boolean listaAgendamentoExportacaoZeusModificada; private List<AgendamentoImportacaoZeus> listaAgendamentoImportacaoZeus; private boolean listaAgendamentoImportacaoZeusModificada; private ParametrosVingentes parametrosVingentes; public Parametros() { this.visaoAtual = VISAO_PARAMETROS_VINGENTES; } @PostConstruct public void init(){ this.conversation.begin(); this.parametrosVingentes = this.parametrosService.getParametrosVingentes(); } public ParametrosVingentes getParametrosVingentes() { return parametrosVingentes; } public List<ValorHora> getListaValorHora(){ if(this.listaValorHora == null || this.listaValorHoraModificada){ this.listaValorHoraModificada = false; this.listaValorHora = this.parametrosService.listarValorHora(); } return this.listaValorHora; } public List<AgendamentoBuscaSistec> getListaAgendamentoBuscaSistec(){ if(this.listaAgendamentoBuscaSistec == null || this.listaAgendamentoBuscaSistecModificada){ this.listaAgendamentoBuscaSistecModificada = false; this.listaAgendamentoBuscaSistec = this.parametrosService.listarAgendamentoBuscaSistec(); } return this.listaAgendamentoBuscaSistec; } public List<AgendamentoExportacaoZeus> getListaAgendamentoExportacaoZeus(){ if(this.listaAgendamentoExportacaoZeus == null || this.listaAgendamentoExportacaoZeusModificada){ this.listaAgendamentoExportacaoZeusModificada = false; this.listaAgendamentoExportacaoZeus = this.parametrosService.listarAgendamentoExportacaoZeus(); } return this.listaAgendamentoExportacaoZeus; } public List<AgendamentoImportacaoZeus> getListaAgendamentoImportacaoZeus(){ if(listaAgendamentoImportacaoZeus == null || this.listaAgendamentoImportacaoZeusModificada){ this.listaAgendamentoImportacaoZeusModificada = false; this.listaAgendamentoImportacaoZeus = this.parametrosService.listarAgendamentoImportacaoZeus(); } return this.listaAgendamentoImportacaoZeus; } public void atualizarParametrosVingentes(){ this.parametrosService.atualizarParametrosVingentes(this.parametrosVingentes); } // Other methods 

And this is JSF:

 <p:fieldset> <h:panelGrid columns="2"> <h:outputLabel value="Valor da hora:" for="valorHoraVingente" /> <p:selectOneMenu id="valorHoraVingente" value="#{parametros.parametrosVingentes.valorHora}"> <f:selectItem itemLabel="Selecione" itemValue="#{null}" /> <f:selectItems value="#{parametros.listaValorHora}" /> </p:selectOneMenu> <h:outputLabel value="Agendamento da Busca do Sistec:" for="agendamentoBuscaSistecVingente" /> <p:selectManyCheckbox id="agendamentoBuscaSistecVingente" value="#{parametros.parametrosVingentes.agendamentosBuscaSistec}"> <f:selectItem itemLabel="Selecione" itemValue="#{null}" /> <f:selectItems value="#{parametros.listaAgendamentoBuscaSistec}" /> </p:selectManyCheckbox> <h:outputLabel value="Agendamento da Exportação para o Zeus:" for="agendamentoExportacaoZeusVingente" /> <p:selectManyCheckbox id="agendamentoExportacaoZeusVingente" value="#{parametros.parametrosVingentes.agendamentosExportacaoZeus}"> <f:selectItem itemLabel="Selecione" itemValue="#{null}" /> <f:selectItems value="#{parametros.listaAgendamentoExportacaoZeus}" /> </p:selectManyCheckbox> <h:outputLabel value="Agendamento da Importação para o Zeus:" for="agendamentoImportacaoZeusVingente" /> <p:selectManyCheckbox id="agendamentoImportacaoZeusVingente" value="#{parametros.parametrosVingentes.agendamentosImportacaoZeus}"> <f:selectItem itemLabel="Selecione" itemValue="#{null}" /> <f:selectItems value="#{parametros.listaAgendamentoImportacaoZeus}" /> </p:selectManyCheckbox> </h:panelGrid> <p:commandButton value="Atualizar" action="#{parametros.atualizarParametrosVingentes}" update="@form" /> </p:fieldset> 

As you can see, the fields are associated with collections to be obtained with LAZY.

And this is the stack trace:

 WARNING: failed to lazily initialize a collection, no session or session was closed org.hibernate.LazyInitializationException: failed to lazily initialize a collection, no session or session was closed at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383) at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375) at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:122) at org.hibernate.collection.PersistentBag.isEmpty(PersistentBag.java:255) at javax.faces.component.UIInput.isEmpty(UIInput.java:1257) at javax.faces.component.UIInput.validateValue(UIInput.java:1144) at javax.faces.component.UISelectMany.validateValue(UISelectMany.java:581) at javax.faces.component.UIInput.validate(UIInput.java:967) at javax.faces.component.UIInput.executeValidate(UIInput.java:1233) at javax.faces.component.UIInput.processValidators(UIInput.java:698) at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214) at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214) at org.primefaces.component.fieldset.Fieldset.processValidators(Fieldset.java:197) at javax.faces.component.UIForm.processValidators(UIForm.java:253) at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214) at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214) at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1172) 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:118) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98) at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174) at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828) at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725) at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019) at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225) at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) at com.sun.grizzly.ContextTask.run(ContextTask.java:71) at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) at java.lang.Thread.run(Thread.java:722) 

I think that at the end of the getParametrosVingentes method of the service, the EntityManager is clear and all entities are separated. Could this be a problem?

I am running this on Glassfish 3 using Mojarra 2.1.2 and EJB 3.1. Thanks for any help.

+4
source share
1 answer

Well, I finally solved the problem! I saw that LazyInitializationException was at the selectManyCheckbox checkout stage. Then I started a search on this link and found this link: http://old.nabble.com/-jira---Created--(MYFACES-3306)-%3Ch%3AselectManyCheckBox%3E-%2B-JPA-with- Hibernate-creates-Hibernate-PersistentCollection-where-it-should-not.-Causes-td32463262.html

The problem was that the JSF was trying to use the PersistentBag created by Hibernate, but it would not use it. The solution was laid by atributte, a JSF-speaking, to use an ArrayList instead of a PersistentBag.

This can be done by adding this inside selectManyCheckbox:

 <f:attribute name="collectionType" value="java.util.ArrayList" /> 
+19
source

Source: https://habr.com/ru/post/1390211/


All Articles