LazyInitializeException...não sei como resolver

3 respostas
D

Opa :smiley:

Tenho uma aplicação web feita com JSF e nela, eu envio um List de relacionamento ManyToMany. Na primeira vez que eu entro, a coleção é recebida corretamente, mas na segunda vez que eu entro nela eu recebo essa exceção de LazyInitializeException e o método que ocorre essa exceção é no:

public List<SelectItem> getProcedimentos() {
		procedimentos = new ArrayList<SelectItem>();
		procedimentos.add(new SelectItem(1000, "Procedimento"));
		for(ProcedimentoBean procedimento : getAgendamentoBean().getSala().getProcedimentos()){ //no metodo getSala().getProcedimentos() eh onde ocorre a exceção...
			procedimentos.add(new SelectItem(procedimento.getId(), procedimento.getNome()));
		}
		return procedimentos;
	}

O mapeamento está da segiunte maneira:

AgendamentoBean

@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "sala_id", insertable = true, updatable = true)
	@Fetch(FetchMode.JOIN)
	private SalaBean sala;

SalaBean

@ManyToMany(fetch=FetchType.LAZY)
	@JoinTable(name="sala_procedimento", joinColumns=@JoinColumn(name="sala_id"), inverseJoinColumns=@JoinColumn(name="procedimento_id"))
	private List<ProcedimentoBean> procedimentos = new ArrayList<ProcedimentoBean>();

e o ProcedimentoBean

@ManyToMany(fetch=FetchType.LAZY)
	@JoinTable(name="sala_procedimento", joinColumns=@JoinColumn(name="procedimento_id"), inverseJoinColumns=@JoinColumn(name="sala_id"))
	private List<SalaBean> salas = new ArrayList<SalaBean>();

Alguém sabe o pq da sessão estar sendo fechada? Eu utilizo aquele OpenSessionView do site do hibernate.

[]'s

David

3 Respostas

fiaux

Eu ia perguntar exatamente sobre o OpenSessionInView, mas você disse que tá usando. É o único lugar que isso dá problema? Verifique o OpenSessionInView. Você pode também dar um jeito de inicializar essa colection antes de chamar esse método, dando um get na propriedade, ou usando um método initialize ou algo assim que tem numa classe do Hibernate. Você precisa dar um jeito de carregar antes desse método ser chamado.

D
package br.com.x.hibernate.filter;

public class HibernateSessionRequestFilter implements Filter {

	private static Log log = LogFactory.getLog(HibernateSessionRequestFilter.class);

	private SessionFactory sf;

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {

		try {
			log.debug("Starting a database transaction");
			sf.getCurrentSession().beginTransaction();

			// Call the next filter (continue request processing)
			chain.doFilter(request, response);

			// Commit and cleanup
			log.debug("Committing the database transaction");
			sf.getCurrentSession().getTransaction().commit();

		} catch (StaleObjectStateException staleEx) {
			log
					.error("This interceptor does not implement optimistic concurrency control!");
			log
					.error("Your application will not work until you add compensation actions!");
			// Rollback, close everything, possibly compensate for any permanent
			// changes
			// during the conversation, and finally restart business
			// conversation. Maybe
			// give the user of the application a chance to merge some of his
			// work with
			// fresh data... what you do here depends on your applications
			// design.
			throw staleEx;
		} catch (Throwable ex) {
			// Rollback only
			ex.printStackTrace();
			try {
				if (sf.getCurrentSession().getTransaction().isActive()) {
					log
							.debug("Trying to rollback database transaction after exception");
					sf.getCurrentSession().getTransaction().rollback();
				}
			} catch (Throwable rbEx) {
				log.error("Could not rollback transaction after exception!",
						rbEx);
			}

			// Let others handle it... maybe another interceptor for exceptions?
			throw new ServletException(ex);
		}
	}

	public void init(FilterConfig filterConfig) throws ServletException {
		log.debug("Initializing filter...");
		log
				.debug("Obtaining SessionFactory from static HibernateUtil singleton");
		sf = InitSessionFactory.getInstance();
	}

	public void destroy() {
	}

Este é o filtro que eu configurei no meu web.xml

<filter>
		<filter-name>HibernateSessionRequestFilter</filter-name>
		<filter-class>
			br.com.x.hibernate.filter.HibernateSessionRequestFilter
		</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>HibernateSessionRequestFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

Como assim? Como que eu posso inicializar isso antes? Pode dar um exemplo? Sempre que eu dou um .getProcedimentos(), ele já me lança a exceção :frowning:

[]'s

D

se eu fizer a chamada dessa maneira:

public List<SelectItem> getProcedimentos() {
		SalaBean sala = new SalaBean();
		SalaDAO dao = new SalaDAO(SalaBean.class);
		sala = (SalaBean)dao.findByID(getAgendamentoBean().getSala().getId());
		procedimentos = new ArrayList<SelectItem>();
		procedimentos.add(new SelectItem(1000, "Procedimento"));
		for(ProcedimentoBean procedimento : sala.getProcedimentos()){
			procedimentos.add(new SelectItem(procedimento.getId(), procedimento.getNome()));
		}
		return procedimentos;
	}

Funciona direitinho…agora não entendo o pq :S

[]'s

Criado 7 de agosto de 2008
Ultima resposta 7 de ago. de 2008
Respostas 3
Participantes 2