Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

LazyInicializationException e Persistencia DETACHED EJB

Não consegui colocar toda a pergunta aqui, por isso postei no gist.

Segue:

https://gist.github.com/anonymous/947a8975211306465b76c13830bd89c6

2 respostas

Obs: No tópico 2, eu disse que quando eu persistia um Recebimento com Cascade, sem EJB e JTA e com RESOURCE_LOCAL a persistencia funcionava normalmente.

Na realidade a persistencia nesse caso funciona normalmente, pois eu não fecho o entity manager na aplicação.

Isso pode levar a vazamento de recursos, então não seria o correto. O correto seria fechar o entity manager.

Mas como controlar isso com EJB se o container que controla a transação.

Detalhando o ciclo do procedimento.

Abro o recebimento.xhtml que possui o bean RecebimentoView - Como @ViewScoped @Named

Dentro do recebimento.xhtml chamo via botão o Dialog Framework - DialogoTipoDeCobrancaView - Como @ViewScoped @Named que abre dialogoTipoDeCobranca.xhtml O bean abre controla o dialogo onde será inserido o valor a ser recebido e selecionado a cobranca pelo Dialog Framework - DialogoCobrancaView

É chamado por um botão dialogoTipoDeCobranca.xhtml o DialogoCobrancaView que abre a seleção das cobrancas cadastradas, selecaoCobrancaView.xhtml.

A selecaoCobrancaView.xhtml retorna uma cobranca já cadastrada para o dialogoTipoDeCobranca.xhtml onde que DialogoTipoDeCobrancaView faz um processamento alterando a situação da Cobranca de "Aberto" para "Pago", além de receber do usuário o valor a ser recebido.

Ao finalizar DialogoTipoDeCobrancaView retorna um objeto de TipoDeCobranca para RecebimentoView, que adiciona o TipoDeCobranca a uma Lista que pode conter vários Tipos de Cobranca.

Quando é finalizado o Recebimento no bean RecebimentoView, desejo fazer o persist via cascade.

No entanto, acontece que a Cobranca fica no estado DETACHED, e se eu dar um find para buscá-la eu perco todas alterações que havia feito nela lá no DialogoTipoDeCobrancaView .

Sendo assim tenho que fazer um for para todas as Cobranças, realizar um merge em cada uma, e após isso Persistir via cascade o Recebimento, que ira Persistir sozinho os Tipos de Cobranca

solução!

Consegui resolver os dois problemas com uma implementação.

Criei uma classe que produz o entity manager do EJB

import java.io.Serializable;
import javax.ejb.Stateful;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;

/**
 *
 * @author Rafael
 */
@Stateful
@ApplicationScoped
public class EntityManagerProducerExtended implements Serializable {

    private static final long serialVersionUID = 1L;

    @PersistenceContext(unitName = "app", type = PersistenceContextType.EXTENDED)
    private EntityManager manager;

    @Produces
    public EntityManager getEntityManager() {
        return manager;
    }

}

assim as classes que precisam do entity manager, não usam mais @Stateless ou @Stateful nem @PersistenceContext, utilizando apenas um @Inject no entity manager.

Assim resolveu o problema do LazyInicializationException entre os Beans (Tópico 1) e também o problema de Detached (Tópico 2).

public class AdicionaDAO<T> implements Serializable {

    @Inject
    private EntityManager em;

    public AdicionaDAO() {
    }

    public void adiciona(T t) throws  DadoInvalidoException {

        try {

            // persiste o objeto e log do mesmo
            em.persist(t);

        } catch (Exception pe) {
            throw new EDadoInvalidoException("Erro" ,pe);
        }
    }
}