Hibernate - could not initialize proxy - the owning Session was closed

2 respostas
Marques

Lista,

Quando tento aceesar o Set abaixo o hibernate me devolve ese erro:
could not initialize proxy - the owning Session was closed.

Se comento a linha session.close() no dao aí funciona.

Como acessar o objeto depois de fechada a sessão?

Muito obrigado,

Marques

método no meu DAO

public Produto getProduto(Long idProduto) {
 		session = DBConnection.getInstance();
 		try {
 			return (Produto) session.load(Produto.class, idProduto);
 		} catch (Exception e) {
 			System.out.println(); 			
 			throw new RuntimeException(e);
 		} finally {
 			if (session != null) {
 				try {
 					session.close();
 				} catch (Exception e) {
 					System.out.println(); 					
 					throw new RuntimeException(e);
 				} 
 			}
 		}		
 	}

A minha classe Produto

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;

@Entity
public class Produto implements Serializable {
	private Long idProduto;
	private String codigoProduto;
	private String codigoBarras;
	private Long unidadeMedida;
	private String descrProduto;
	private ProdutoSubnivel subnivel;
	private BigDecimal estoqueMinimo;
	private String localizacao;
	private BigDecimal pesoLiquido;
	private Long idSituacaoTrib;
	private Long idCodigoNCM;	
	private Set<ContaContabil> contaContabil;
	
	//outros getters e setters
	
	@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
	public Long getIdProduto() {
		return idProduto;
	}
	public void setIdProduto(Long idProduto) {
		this.idProduto = idProduto;
	}
	@ManyToOne(fetch = FetchType.EAGER)	
	@JoinColumn(name = "idSubnivel")
	public ProdutoSubnivel getSubnivel() {
		return subnivel;
	}
	
	@ManyToMany(fetch = FetchType.EAGER,
			targetEntity=ContaContabil.class, cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})			
	@JoinTable(
	         name="ProdutoContaContabil",
	         joinColumns={@JoinColumn(name="idProduto", table="contaContabil")},
	         inverseJoinColumns = @JoinColumn( name="idContaContabil"))   
	public Set<ContaContabil> getContaContabil() {
		return contaContabil;
	}
	
	public void setContaContabil(Set<ContaContabil> contaContabil) {
		this.contaContabil = contaContabil;
	}
}

A classe onde tento acessar o Produto

Produto produto = produtoDAO.getProduto(idProduto);		
Set<ContaContabil> contas = produto.getContaContabil();

2 Respostas

andreiribas

hm… se não me engano coloca lazy = false no mapeamento dessa classe

T

Modificar o lazy para false é tapar o sol com a peneira, quando vc fecha a Session o objeto passa para estado de Detached, ou seja, ele não esta associado a nenhuma Session então não consegue acessar o BD por isso ocorra a Exception. Para associar ele novamente a uma Session vc pode utilizar os métodos update(), saveOrUpdate() ou lock(). Para o que esta fazendo recomendo que utilize o Lock, com isso seu código deve funcionar mas vc vai ver que a syntax do seu código vai ficar estranha, pq vc vai pedir pro DAO o objeto e em seguida vai ter de associá-lo a uma Session. Se estiver programando pra Web recomendo que leia sobre o padrão OSIV (Open Session In View).

Boa Sorte!

Criado 12 de abril de 2007
Ultima resposta 12 de abr. de 2007
Respostas 2
Participantes 3