Dúvida ao executar lista Lazy

Olá, pessoal, tudo bem?
Tenho no meu projeto 3 entidades, sendo elas - doador, receptor e atendimento.
O Usuário pode se permitir cadastrar doadores e receptores indistintamente, porém, ao cadastrar um atendimento, deverá escolher em uma lista, vários doadores e receptores.
O.k. tudo bem até aí.
Porém ao listar, tenho um problema - esta excessão:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: br.com.agets.dominio.Atendimento.doadores, no session or session was closed
	at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
	at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)

AtendimentoDAO

public List<Atendimento> listarTodosOrdenadosPelasMaisAntigos() {
		return this.getSession().createCriteria(Atendimento.class).addOrder(Order.desc("dataAtendimento")).list();
	}

Tenho esta referência na entidade Receptor:


	@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinTable(name = "receptor_atendimento", joinColumns = { @JoinColumn(name = "ID_RECEPTOR") }, inverseJoinColumns = { @JoinColumn(name = "ID_ATENDIMENTO") })
	private List<Atendimento> atendimentos;

e esta na classe Doador também:

@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinTable(name = "doador_atendimento", joinColumns = { @JoinColumn(name = "ID_DOADOR") }, inverseJoinColumns = { @JoinColumn(name = "ID_ATENDIMENTO") })
	private List<Atendimento> atendimentos;

E isto na entidade Atendimento:

@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinTable(name = "doador_atendimento", joinColumns = { @JoinColumn(name = "ID_ATENDIMENTO") }, inverseJoinColumns = { @JoinColumn(name = "ID_DOADOR") })
	private List<Doador> doadores = new ArrayList<Doador>();

	@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinTable(name = "receptor_atendimento", joinColumns = { @JoinColumn(name = "ID_ATENDIMENTO") }, inverseJoinColumns = { @JoinColumn(name = "ID_RECEPTOR") })
	private List<Receptor> receptores = new ArrayList<Receptor>();

O resultado disso é o que eu espero, cria um relacionamento muitos para muitos de Atendimento para Doador e Atendimento para Receptor, e para ambos, uma tabela adicional atendimento_doador e atendimento_receptor.

isto era só para entender a estrutura, mas meu problema está no service:

public List<Atendimento> listarTodos() {
		DAOFactory daoFactory = DAOFactory.getDAOFactory();
		AtendimentoDAO atendimentoDAO = daoFactory.getAtendimentoDAO();
		List<Atendimento> atendimentos = atendimentoDAO.listarTodosOrdenadosPelasMaisAntigos();
///ESTE É O MEU PROBLEMA, SE RETIRAR A CHAMADA Á "ENCERRAR" FUNCIONA.
		daoFactory.encerrar();
		return atendimentos;

Como comentei o código, se retirar a chamada à ENCERRAR, funciona, mas é a maneira certa de resolver, a minha conexão simplesmente ficará aberta?
Abaixo a minha classe HIBERNATEDAOFactory contendo o método Encerrar e outros para obtenção das sessões.

public class HibernateDAOFactory extends DAOFactory {
	private Session session;
	private Transaction tx;

	public HibernateDAOFactory() {
		this.session = HibernateUtil.getSession();
	}

	@Override
	public void cancelarTransacao() {
		this.tx.rollback();
		this.tx = null;
	}

	@Override
	public void iniciarTransacao() {
		this.tx = this.session.beginTransaction();

	}

	@Override
	public void encerrar() {
		if (this.tx != null) {
			this.tx.commit();
		}
		this.session.close();

	}

	@Override
	public DoadorDAO getDoadorDAO() {
		return new HibernateDoadorDAO(this.session);
	}

	@Override
	public AtendimentoDAO getAtendimentoDAO() {
		return new HibernateAtendimentoDAO(this.session);
	}

	@Override
	public ReceptorDAO getReceptorDAO() {
		return new HibernateReceptorDAO(this.session);
	}

}

Por favor, preciso de ajuda. Como resolver?

para vc corrigir isso no seu metodo listarTodosOrdenadosPelasMaisAntigos, voce deve mandar o hibernate recarregar todos os objetos antes de pedir para ele acessar… caso contrario ele vai acessar um objeto que nao foi carregado e vai dar lazyexception…

PS: quando falo em recarregar, digo no sentido de vc mandar ele pesquisar cada um dos objetos que esta na lista… no caso o hibernate só trouxe a referencia mas nao puxou os dados… basta vc fazer uma pesquisar para cada referencia que ja vai funcionar…

Olá, meu caro, tudo bem?
Mas a idéia é uma lista com todos os atributos de “Atendimento”, como no atendimento teria Doadores e receptores, gostaria apenas de listar todos eles…
Creio que essa teria sido sua idéia, me corrija se estiver errado, mas receio ter imaginado fazer isso por demanda…
mas apenas pensei em listar todos…
Imagino que realmente a sua sugestão faz sentido, pode me dizer como faço isso no código?

Muito obrigado.

Esse post vai te ajudar: Quatro soluções para LazyInitializationException.

Olá Hebert, tudo bem?
Será que resolveria alterando a query para então carregar os valores dos atributos da lsita de Doadores?
Usando a dica do colega?

[quote=smnj]Olá Hebert, tudo bem?
Será que resolveria alterando a query para então carregar os valores dos atributos da lsita de Doadores?
Usando a dica do colega?
[/quote]Você tentou? Qual foi o resultado? [=

Hebert, a solução mais aplicável, é a da página 7.
Porém preciso de listar à partir de Atendimento doadores e receptores, sem passagem de parâmetros, como faz no teu exemplo.

Tentei sim, quero fazer uma busca usando a dica da página 7, a dúvida está só sendo de com obter a lista sem os parâmetros usados no exemplo.

[quote=smnj]Tentei sim, quero fazer uma busca usando a dica da página 7, a dúvida está só sendo de com obter a lista sem os parâmetros usados no exemplo.[/quote]Tentou fazer sem adicionar parâmetro na consulta?

Isso funcionaria?

	public List<Atendimento> listarTodosOrdenadosPelasMaisAntigos() {
		return (List<Atendimento>) this.getSession().createQuery("select a from Atendimento A join fetch a.atendimento");

Só que não retornando um único registro, mas uma lista.