Como resolver o LazyException nesse cenario? (JPA + EJB + JSF)

2 respostas
faeldix

Seguinte.. vou apresentar meu cenario:

[size=18]Tenho um projeto JPA (com os meus models)[/size]

ex:

@Entity(name = "Paciente")
@Table(name = "PACIENTE")
public class Paciente {

	public Paciente() {
		patologias = new ArrayList<Patologia>();
		patologiasFamilia = new ArrayList<Patologia>();
	}

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "ID")
	private Integer id;

	@Column(name = "CPF", nullable = false, unique = true)
	private String cpf;

	@Column(name = "NOME", nullable = false)
	private String nome;

	@Column(name = "DATA_NASCIMENTO")
	@Temporal(TemporalType.DATE)
	private Date dataNascimento;

	@Column(name = "SEXO")
	private Character sexo;

	public Character getSexo() {
		return sexo;
	}

	@Column(name = "PRESSAO_SISTOLICA")
	private String pressaoSistolica;

	@Column(name = "PRESSAO_DIASTOLICA")
	private String pressaoDiastolica;

	@Column(name = "AVATAR_SRC")
	private String srcAvatar;

	@OneToOne
	@JoinColumn(name = "FK_PACIENTE_BIOTIPO_ID")
	private PacienteBiotipo biotipo;

	@OneToOne
	@JoinColumn(name = "FK_GRUPO_PACIENTE_ID")
	private PacienteGrupo grupo;

	@OneToOne
	@JoinColumn(name = "FK_OBJETIVO_ID")
	private PacienteObjetivo objetivo;

	@ManyToMany
	@JoinTable(name = "PACIENTE_PATOLOGIA", joinColumns = @JoinColumn(name = "FK_PACIENTE_ID"), inverseJoinColumns = @JoinColumn(name = "FK_PATOLOGIA_ID"))
	private Collection<Patologia> patologias;

	@ManyToMany
	@JoinTable(name = "PACIENTE_PATOLOGIA_FAMILIAR", joinColumns = @JoinColumn(name = "FK_PACIENTE_ID"), inverseJoinColumns = @JoinColumn(name = "FK_PATOLOGIA_ID"))
	private Collection<Patologia> patologiasFamilia;

[size=8]Tenho um projeto EJB (onde possui os dao (interfaces e implementacoes)[/size]

public interface DAO<T> extends Repository<T> {

//	public T get(Object id) throws Exception;

	public void delete(T object) throws Exception;
	public void delete(Collection<T> objects) throws Exception;
	public void delete(Integer id) throws Exception;

	public void add(T t) throws Exception;
	public void addOrUpdate(T t) throws Exception;
	public void update(T t) throws Exception;
	
	public void refresh(T t) throws Exception;

}
@Local
public interface DAOPaciente extends DAO<Paciente> {

	public Paciente getPacienteByCPF(String cpf) throws Exception;

}
implementacao:
@Stateless
public class JPAPaciente implements DAOPaciente {

	@PersistenceContext
	private EntityManager manager;

	@Override
	public void delete(Paciente object) {
		manager.remove(object);
	}

	@Override
	public void delete(Collection<Paciente> objects) {
		for (Paciente paciente : objects) {
			manager.remove(paciente);
		}
	}

	@Override
	public void delete(Integer id) {
		manager.remove(id);
	}

	@Override
	public void add(Paciente t) {
		manager.persist(t);
	}

	@Override
	public void addOrUpdate(Paciente t) {
		Paciente paciente = manager.find(Paciente.class, t);

		if (paciente != null) {
			manager.merge(paciente);
		} else {
			manager.persist(t);
		}
	}

	@Override
	public void update(Paciente t) {
		manager.merge(t);
	}

	@Override
	public void refresh(Paciente t) {
		manager.refresh(t);
	}

	@Override
	public Paciente getPacienteByCPF(String cpf) {
		TypedQuery<Paciente> query = manager.createQuery(
				"SELECT p FROM Paciente p WHERE p.cpf = :cpf", Paciente.class);
		query.setParameter(1, cpf);

		return query.getSingleResult();
	}

	@Override
	public Collection<Paciente> getAll() {
		TypedQuery<Paciente> query = manager.createQuery(
				"SELECT p FROM Paciente p", Paciente.class);
		return query.getResultList();
	}

	@Override
	public Paciente get(Object id) {
		return manager.find(Paciente.class, id);
	}

}

e o EJB

@Stateless
public class PacienteService implements PacienteBusiness {

	@EJB
	private DAOPaciente dao;

	public void add(Paciente paciente) throws Exception {
		dao.add(paciente);
	}

	public void delete(Paciente paciente) throws Exception {
		dao.delete(paciente);
	}

	public void delete(Integer id) throws Exception {
		dao.delete(id);
	}

	@Override
	public Collection<Paciente> getAll() {
		return dao.getAll();
	}

	@Override
	public Paciente get(Integer id) {
		return dao.get(id);
	}

	@Override
	public void refresh(Paciente paciente) {
		try {
			dao.refresh(paciente);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

Quando estou na pagina JSF que quero mostrar as patologias de um paciente em particular.. atraves de uma requisicao get (/paciente?id=2) quando o JSF faz o get de patologias.. é jogada uma Exception

failed to lazily initialize a collection of role: br.com.nutrimobi.models.Paciente.patologias, no session or session was closed

Ja entendi que isso ocorre devido o fato do "EntityManager" [injetado no EJB via AS] esta sendo fechado antes da renderizacao da pagina..

A PERGUNTA É: Como manter esse EntityManager aberto durante a renderizacao da pagina???
grato!

2 Respostas

Hebert_Coelho

Esse post pode te ajudar:

http://uaihebert.com/quatro-solucoes-para-lazyinitializationexception/

faeldix

Hebert Coelho:
Esse post pode te ajudar:

http://uaihebert.com/quatro-solucoes-para-lazyinitializationexception/

Caso eu tiver um relacionamento bi-direcional (no caso, eu nao tenho)…
Utilizando o filtro eu teria um stackoverflow entao?

Criado 9 de fevereiro de 2014
Ultima resposta 9 de fev. de 2014
Respostas 2
Participantes 2