Question

I ai un CDI Managed Bean (haricot annoté avec @Named qui est utilisé sur JSF) qui a une session Stateful Bean injecté. Ce haricot de session est comme un service, il a le gestionnaire d'entités (annotée avec @PersistenceContext (type = PersistenceContextType.EXTENDED)) et d'exposer les méthodes venir pour manipuler certaines entités. Ces entités sont sur le bean géré, qui est ConversationScoped. Ensuite, le JSF appelle une méthode de la fève gérée et le bean géré appelle une méthode du « service » (le bean session stateful). Je ne sais pas si c'est la meilleure conception, mais il fonctionnait bien. Mais il y a une entité qui ont des collections qui ont besoin d'être tiré par les cheveux avec lazy. Et la première fois que j'ouvre la page, il semble bien fonctionner, mais lorsque je tente de cliquer sur un bouton ou faire une action, je le LazyInitializationException. Ce que quelqu'un a une astuce? Je ne sais pas s'il y a quelque chose de mal. Je mets le bean session comme contexte stateful et la persistance prolongée. Ce haricot de session est injectée dans le bean géré, qui a les entités. Pourquoi il est jeter cette exception? Comment le directeur de l'entité pourrait être fermée?

Ceci est le code de l'entité qui est en difficulté:

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

Voici la Stateful Session Bean:

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

}

Le managed bean appelle la méthode getParametrosVingentes () de la fève de session. I utilise une méthode statique de la ParametrosUtil pour obtenir (si elle existe) ou de créer (si elle n'existe pas) les ParametrosVingentes. Il est parce qu'il est nécessaire qu'il n'y a qu'un seul ParametrosVingentes dans l'application. Il est le grain qui a les paramètres utilisés par d'autres composants. Voici le code de ParametrosUtil:

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

Ceci est le bean géré:

@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

Et voici le 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>

Comme vous pouvez le voir, il y a des champs se lier avec les collections qui doivent être extraites avec lazy.

Et c'est la trace de la pile:

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)

Je pense qu'à la fin de la méthode getParametrosVingentes du service, la EntityManager est claire et toutes les entités sont détachés. Se pourrait-il le problème?

Je suis en cours d'exécution sur ce Glassfish 3, en utilisant Mojarra 2.1.2 et 3.1 EJB. Merci pour toute aide.

Était-ce utile?

La solution

Eh bien, je me suis finalement résolu le problème! J'ai vu le LazyInitializationException était dans la phase de validation du selectManyCheckbox. Puis j'ai commencé la recherche pour cela et trouvé ce lien: http://old.nabble.com/-jira---Created- - (MyFaces-3306) -% 3Ch% 3AselectManyCheckBox% 3E-% 2B-JPA avec Hibernate-crée-Hibernate-PersistentCollection-où-il-faut-not.-Causes-td32463262.html-

Le problème est que le JSF essayait d'utiliser le PersistentBag créé par la mise en veille prolongée, mais il ne serait pas l'utiliser. La solution a été mis un atributte dire le JSF d'utiliser un ArrayList au lieu du PersistentBag.

Il peut être fait en ajoutant ceci à l'intérieur du selectManyCheckbox:

<f:attribute name="collectionType" value="java.util.ArrayList" />
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top