Erro Validator VRaptor + Session Hibernate [Resolvido]

18 respostas
robertouba

Salve galera, estou com um problema que não entendi o motivo. Mas está bizarro!

public void deletar(Empresa empresa) {
	Empresa empresaDB = this.empresaDao.loadPorNome(empresa);
	try {
	    this.empresaDao.delete(empresaDB);
	} catch (ConstraintViolationException e) {
	    this.validator.add(new ValidationMessage(e.getCause().getMessage(), "Erro de Bando de Dados"));
	    e.printStackTrace();
	} catch (PropertyValueException e) {
	    this.validator.add(new ValidationMessage(e.getCause().getMessage(), "Erro de Bando de Dados"));
	    e.printStackTrace();
	}
	this.validator.onErrorForwardTo(this).listar();
	this.result.redirectTo(this).listar();
    }

Bom, quando tento fazer o delete, ele gera erro, pela FK claro, porém o validator não consegue enviar para a página listar, no mesmo controller tem validators e está funcionando normalmente, e usando e do mesmo jeito, apenas não entendi, ele não chega a redirecionar, ele simplesmente para no onErrorForward e aparece o erro:

18 Respostas

Lucas_Cavalcanti

dá uma olhada na última exceção (a root).

O erro é com por causa do hibernate.
Você deu try …catch numa exceção do hibernate, e depois deu forward pra lógica de listar, que usa a mesma sessão que já está marcada com erro. Se você trocar pelo redirect, que faz outra requisição, e portanto outra sessão, deve funcionar.

robertouba

Caraca, que estranho
o que achei muito estranho é, bom, o erro foi de FK o que acontece em vários momentoos da minha aplicação, porém, redireciona sempre com Forward e, (já havia até esqueciso que existia o Redirec), mesmo usando Foward ele funcionou.

Entende?

Lucas_Cavalcanti

entendo… pesquisa sobre o último erro pra ver as condições que ele acontece. Provavelmente é um caso diferente.

robertouba

certo, obrigado, sempre Lucas!

tefo

eai galera!!

estou com um problema muito parecido.. soh que aqui ocorre no momento de deletar um produto!

ProdutosController.java
package br.com.caelum.website.controller;

import java.util.List;

import br.com.caelum.vraptor.Delete;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Put;
import br.com.caelum.vraptor.Resource; 
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;
import br.com.caelum.website.dao.ProdutoDao;
import br.com.caelum.website.interceptor.Restrito;
import br.com.caelum.website.modelo.Produto;
import static br.com.caelum.vraptor.view.Results.*;

@Resource
public class ProdutosController {

	private final ProdutoDao dao;
	private final Result result;
	private final Validator validator;
	
	public ProdutosController(ProdutoDao dao, Result result, Validator validator) { 
		this.dao = dao;
		this.result = result;
		this.validator = validator;
	}
	
	@Get @Path("/produtos")
	public List<Produto> lista() {
		return dao.listaTudo();
	}
	
	@Restrito
	@Post @Path("/produtoAdiciona")
	public void adiciona(final Produto produto) { 
		validaProduto(produto);
		dao.salva(produto);
		result.redirectTo(this).lista();
	}
	
	@Restrito
	@Get @Path("/produtos/novo")
	public void formulario() { 
	}
	
	@Restrito
	@Get @Path("/produtoCarrega/{id}")
	public Produto edita(Long id) {
		return dao.carrega(id);
	}
	
	@Restrito
	@Put @Path("/produtoAltera/{produto.id}")
	public void altera(Produto produto) {
		validaProduto(produto);
		dao.atualiza(produto); 
		result.redirectTo(this).lista();
	}
	
	@Restrito
	@Delete @Path("/produtoRemove/{id}")
	public void remove(Long id) {
		Produto produto = dao.carrega(id); 
		dao.remove(produto); 
		result.redirectTo(this).lista();
	}
	
	@Get @Path("/produtos/busca.json")
	public void buscaJson(String q) {
		result.use(json()).withoutRoot().from(dao.busca(q)).exclude("id", "descricao").serialize();
	}
	
	private void validaProduto(final Produto produto) {
		validator.validate(produto); 
		validator.onErrorUsePageOf(ProdutosController.class).formulario();
	}
	
	public List<Produto> busca(String nome) { 
		result.include("nome", nome); 
		return dao.busca(nome);
	}

}
ProdutoDao.java
package br.com.caelum.website.dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.website.modelo.Produto;

@Component
public class ProdutoDao {
	
	@Autowired
	private Session session;
	
	public ProdutoDao() { 
	}
	
	public Session getSession() {
		return this.session;
	}
	
	public void setSession(Session session) {
		this.session = session;
	}
	
	@Transactional
	public void salva(Produto produto) {
		this.session.save(produto); 
	}

	@Transactional
	public void atualiza(Produto produto) { 
		this.session.update(produto); 
	}

	@Transactional
	public void remove(Produto produto) {
		this.session.delete(produto);
	}
	
	public Produto carrega(Long id){
		return (Produto) this.session.load(Produto.class, id);
	}
	
	public List<Produto> listaTudo() { 
		return this.session.createCriteria(Produto.class).list();
	}

	public List<Produto> busca(String nome) {
		return session.createCriteria(Produto.class).add(Restrictions.ilike("nome", nome, MatchMode.ANYWHERE)) .list();
	}
	
	public void recarrega(Produto produto) { 
		session.refresh(produto);
	}

}
Console do Eclipse (no browser da HTTP Status 500 -)
14/06/2012 23:15:28 org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() for servlet default threw exception
br.com.caelum.vraptor.InterceptionException: exception raised, check root cause for details: net.vidageek.mirror.exception.ReflectionProviderException: Could not invoke method delete
	at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:96)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:61)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:87)
	at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	at br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:71)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44)
	at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
	at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)
	at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Thread.java:680)
Caused by: net.vidageek.mirror.exception.ReflectionProviderException: Could not invoke method delete
	at net.vidageek.mirror.provider.java.PureJavaMethodReflectionProvider.invoke(PureJavaMethodReflectionProvider.java:45)
	at net.vidageek.mirror.invoke.MethodHandlerByMethod.withArgs(MethodHandlerByMethod.java:54)
	at br.com.caelum.website.infra.CriadorDeSession$1.intercept(CriadorDeSession.java:37)
	at br.com.caelum.website.infra.CriadorDeSession$1.intercept(CriadorDeSession.java:1)
	at br.com.caelum.vraptor.proxy.CglibProxifier$2.intercept(CglibProxifier.java:95)
	at org.hibernate.Session$$EnhancerByCGLIB$$94130a79.delete(<generated>)
	at br.com.caelum.website.dao.ProdutoDao.remove(ProdutoDao.java:43)
	at br.com.caelum.website.dao.ProdutoDao$$FastClassByCGLIB$$21c13fee.invoke(<generated>)
	at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
	at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
	at br.com.caelum.website.dao.ProdutoDao$$EnhancerByCGLIB$$f3ffc5df.remove(<generated>)
	at br.com.caelum.website.controller.ProdutosController.remove(ProdutosController.java:67)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:61)
	... 39 more
Caused by: org.hibernate.HibernateException: illegally attempted to associate a proxy with two open Sessions
	at org.hibernate.proxy.AbstractLazyInitializer.setSession(AbstractLazyInitializer.java:126)
	at org.hibernate.engine.StatefulPersistenceContext.reassociateProxy(StatefulPersistenceContext.java:573)
	at org.hibernate.engine.StatefulPersistenceContext.unproxyAndReassociate(StatefulPersistenceContext.java:618)
	at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:89)
	at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:73)
	at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:956)
	at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:934)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at net.vidageek.mirror.provider.java.PureJavaMethodReflectionProvider.invoke(PureJavaMethodReflectionProvider.java:38)
	... 59 more

Alguem tem uma dica?

robertouba

E ai, tudo bem?

Responde uma coisa, ele deletou?

tefo

tudo bem cara…

o produto nao foi deletado… continua la no banco intacto

Lucas_Cavalcanti

como vc está criando a Session? tá usando algum proxy pra ela?

tefo

eu estava seguindo a apostila da Caelum fj-28 onde tem os dois seguintes arquivos no projeto:

CriadorDeSession.java
package br.com.caelum.website.infra;

import net.vidageek.mirror.dsl.Mirror;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.SessionFactoryUtils;

import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.ioc.ComponentFactory;
import br.com.caelum.vraptor.proxy.MethodInvocation;
import br.com.caelum.vraptor.proxy.Proxifier; 
import br.com.caelum.vraptor.proxy.SuperMethod;

import java.lang.reflect.Method;

@Component
public class CriadorDeSession implements ComponentFactory<Session> {

	private final SessionFactory factory;
	private final Proxifier proxifier;
	private Session session;
	
	public CriadorDeSession(SessionFactory factory, Proxifier proxifier) { 
		this.factory = factory; 
		this.proxifier = proxifier;
	}
	
	@PostConstruct
	public void abre() { 
		this.session = proxifier.proxify(Session.class, new MethodInvocation<Session>() {
			public Object intercept(Session proxy, Method method, Object[] args, SuperMethod superMethod) {
				Session sessionDoSpring = SessionFactoryUtils.doGetSession(factory, true); 
				return new Mirror().on(sessionDoSpring).invoke().method(method).withArgs(args);
			}
		});
	} 
	
	public Session getInstance() {
		return this.session;
	}
	
	@PreDestroy
	public void fecha() { 
		this.session.close();
	}

}
e CriadorDeSessionFactory.java
package br.com.caelum.website.infra;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

import br.com.caelum.vraptor.ioc.ApplicationScoped;
import br.com.caelum.vraptor.ioc.ComponentFactory;

@ApplicationScoped
public class CriadorDeSessionFactory implements ComponentFactory<SessionFactory> {
	
	private SessionFactory factory;
	
	@PostConstruct
	public void abre() { 
		AnnotationConfiguration configuration = new AnnotationConfiguration(); 
		configuration.configure();
		this.factory = configuration.buildSessionFactory();
	} 
	
	public SessionFactory getInstance() {
		return this.factory;
	}
	
	@PreDestroy
	public void fecha() { 
		this.factory.close();
	}

}

dai comecei a usar o Spring e acontecia um outro erro (que foi solucionado em outro topic aqui) onde tive que apagar o construtor da classe ProdutoDao onde setava a session e passei a usar metodos gets e sets para setar o atributo session que passei a anota-lo com @Autowired..

acho que foi soh isso que aconteceu...

Lucas_Cavalcanti

o problema é que o SessionFactoryUtils.doGetSession(factory, true); abre uma session nova a cada vez que vc chama, então ele tá abrindo uma session pro load (que só carrega um proxy) e outra pro delete, por isso que o hibernate deu aquele erro (proxy associated with two open sessions)

pra resolver isso, vc precisa cachear a sessão do spring:

if (this.sessionDoSpring == null) {
     this.sessionDoSpring = SessionFactoryUtils.doGetSession(factory, true);   
}
return new Mirror().on(this.sessionDoSpring).invoke().method(method).withArgs(args);
tefo

na classe CriadorDeSession alterei o metodo para:

@PostConstruct public void abre() { this.session = proxifier.proxify(Session.class, new MethodInvocation<Session>() { public Object intercept(Session proxy, Method method, Object[] args, SuperMethod superMethod) { Session sessionDoSpring = SessionFactoryUtils.doGetSession(factory, true); if (session == null) { session = SessionFactoryUtils.doGetSession(factory, true); } return new Mirror().on(sessionDoSpring).invoke().method(method).withArgs(args); } }); }
e da o mesmo erro:

15/06/2012 00:54:02 org.apache.catalina.core.StandardWrapperValve invoke GRAVE: Servlet.service() for servlet default threw exception br.com.caelum.vraptor.InterceptionException: exception raised, check root cause for details: net.vidageek.mirror.exception.ReflectionProviderException: Could not invoke method delete at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:96) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:61) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:71) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:87) at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44) at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92) at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58) at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) at java.lang.Thread.run(Thread.java:680) Caused by: net.vidageek.mirror.exception.ReflectionProviderException: Could not invoke method delete at net.vidageek.mirror.provider.java.PureJavaMethodReflectionProvider.invoke(PureJavaMethodReflectionProvider.java:45) at net.vidageek.mirror.invoke.MethodHandlerByMethod.withArgs(MethodHandlerByMethod.java:54) at br.com.caelum.website.infra.CriadorDeSession$1.intercept(CriadorDeSession.java:40) at br.com.caelum.website.infra.CriadorDeSession$1.intercept(CriadorDeSession.java:1) at br.com.caelum.vraptor.proxy.CglibProxifier$2.intercept(CglibProxifier.java:95) at org.hibernate.Session$$EnhancerByCGLIB$$efe48cc.delete(<generated>) at br.com.caelum.website.dao.ProdutoDao.remove(ProdutoDao.java:43) at br.com.caelum.website.dao.ProdutoDao$$FastClassByCGLIB$$21c13fee.invoke(<generated>) at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149) at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621) at br.com.caelum.website.dao.ProdutoDao$$EnhancerByCGLIB$$c638a4ba.remove(<generated>) at br.com.caelum.website.controller.ProdutosController.remove(ProdutosController.java:67) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:61) ... 39 more Caused by: org.hibernate.HibernateException: illegally attempted to associate a proxy with two open Sessions at org.hibernate.proxy.AbstractLazyInitializer.setSession(AbstractLazyInitializer.java:126) at org.hibernate.engine.StatefulPersistenceContext.reassociateProxy(StatefulPersistenceContext.java:573) at org.hibernate.engine.StatefulPersistenceContext.unproxyAndReassociate(StatefulPersistenceContext.java:618) at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:89) at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:73) at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:956) at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:934) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at net.vidageek.mirror.provider.java.PureJavaMethodReflectionProvider.invoke(PureJavaMethodReflectionProvider.java:38) ... 59 more

acho que coloquei o que vc disse no lugar certo…
pois nao tem logica fazer isso:

@PostConstruct public void abre() { this.session = proxifier.proxify(Session.class, new MethodInvocation<Session>() { public Object intercept(Session proxy, Method method, Object[] args, SuperMethod superMethod) { Session sessionDoSpring = SessionFactoryUtils.doGetSession(factory, true); if (sessionDoSpring == null) { sessionDoSpring = SessionFactoryUtils.doGetSession(factory, true); } return new Mirror().on(sessionDoSpring).invoke().method(method).withArgs(args); } }); }

ou eu fiz errado?

tefo

Desculpe, sim, tinha feito errado…

fiz da seguinte maneira e os erros sumiram:

@PostConstruct public void abre() { this.session = proxifier.proxify(Session.class, new MethodInvocation<Session>() { private Session sessionDoSpring; public Object intercept(Session proxy, Method method, Object[] args, SuperMethod superMethod) { //Session sessionDoSpring = SessionFactoryUtils.doGetSession(factory, true); if (this.sessionDoSpring == null) { this.sessionDoSpring = SessionFactoryUtils.doGetSession(factory, true); } return new Mirror().on(this.sessionDoSpring).invoke().method(method).withArgs(args); } }); }

MAS…

mas o objeto nao eh deletado do banco de dados…
debugando o metodo ‘carrega’ (este metodo nao tem a anotaçao @Transactional, precisa?) da classe ProdutoDao public Produto carrega(Long id){ return (Produto) this.session.load(Produto.class, id); } encontrei dentro de this.session > CGLIB$CALLBACK_0 > valShandler > sessionDoSpring = null
e assim ao executar a linha do metodo ‘load’ eh retornado um objeto Produto contendo id = null, nome = null, descricao = null e preco = null (sem erros)
***o estranho é que isso acontece também quando o produto é carregado para edição, por exemplo, e os valores são carregados e exibidos para edição normalmente…

a aplicaçao continua a execuçao das linhas de codigo ateh chegar no metodo ‘remove’ da classe ProdutoDao @Transactional public void remove(Produto produto) { this.session.delete(produto); } onde recebe aquele produto com os atributos nulos e executa o metodo ‘delete’ da session que agora sim tem como valor um objeto SessionImpl this.session > CGLIB$CALLBACK_0 > valShandler > sessionDoSpring = SessionImpl e que por sua vez nao ocorre erro mas acaba por nao deletar o produto!

Notei mais algumas situaçoes:

  • todas as outras operaçoes da aplicaçao que acessam o banco (exceto a operaçao de deletar) funcionam normalmente, que sao as operaçoes onde o valor de session eh this.session > CGLIB$CALLBACK_0 > valShandler > sessionDoSpring = null
  • o metodo ‘remove’ da classe ProdutosController eh o unico dos metodos que acessa o dao mais de uma vez:

@Restrito @Delete @Path("/produtoRemove/{id}") public void remove(Long id) { Produto produto = dao.carrega(id); dao.remove(produto); result.redirectTo(this).lista(); }ou seja, na primeira passada pelo dao a sessionDoSpring eh null… mas na segunda (no metodo remove) nao…
Obs.: minhas classes ProdutosController e ProdutoDao ja foram postadas acima…

nao tenho muito conhecimento sobre isso, mas acredito que com essas informaçoes ja eh possivel ter um diagnostico…
alguem pode me ajudar?

Lucas_Cavalcanti

vc tá usando o @Transactional do spring?

se sim, tem uma solução melhor do que essa de cachear a sessionDoSpring.

basta vc registrar o OpenSessionInViewFilter do spring. (e voltar pra versão antiga da sua classe CriadorDeSession)

tefo

to usando esse Transactional import org.springframework.transaction.annotation.Transactional;
só tem um problema… eu não entendi/não sei fazer isso que você disse: “registrar o OpenSessionInViewFilter do spring”…

podes me dizer onde e como fazer isso?

Lucas_Cavalcanti

https://www.google.com.br/?q=spring+opensessioninviewfilter

:wink:

é um filtro, só registrar no web.xml e apontar pro seu applicationcontext.xml do spring.

tefo

eu procurei como se configura OpenSessionInViewFilter e o que eu encontrei foram as seguintes configurações:

- voltei ao normal a classe CriadorDeSession (sem cachear) conforme você disse;

- meu web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  
  <display-name>website</display-name>
  
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <session-config>
    <session-timeout>10</session-timeout>
  </session-config>
  
  <context-param>
    <param-name>javax.servlet.jsp.jstl.fmt.locale</param-name>
    <param-value>pt_BR</param-value>
  </context-param>
  
  <context-param>
  	<param-name>contextConfigLocation</param-name>
  	<param-value>/WEB-INF/applicationContext.xml</param-value>
  </context-param>
  
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <!-- Configuraçao para o OpenSessionInViewFilter -->
  <filter>
      <filter-name>openSessionInViewFilter</filter-name>
      <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
      <init-param>
      	<param-name>sessionFactoryBeanName</param-name>
      	<param-value>sessionFactory</param-value>
      </init-param>
   </filter>
   
   <filter-mapping>
      <filter-name>openSessionInViewFilter</filter-name>
      <url-pattern>/*</url-pattern>
      <dispatcher>FORWARD</dispatcher>
      <dispatcher>REQUEST</dispatcher>
   </filter-mapping>

  <filter>
    <filter-name>vraptor</filter-name>
    <filter-class>br.com.caelum.vraptor.VRaptor</filter-class>
  </filter>
  
  <filter-mapping>
  	<filter-name>vraptor</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
  </filter-mapping>
  
  <jsp-config>
    <jsp-property-group>
      <description>crddv</description>
      <display-name>Controle de Receitas, Depósitos e ©bitos de Valores</display-name>
      <url-pattern>*.jsp</url-pattern>
      <include-prelude>/header.jspf</include-prelude>
      <include-coda>/footer.jspf</include-coda>
    </jsp-property-group>
  </jsp-config>
  
</web-app>
- meu applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	   xmlns:tx="http://www.springframework.org/schema/tx"
	   xsi:schemaLocation="
	   		http://www.springframework.org/schema/beans 
	   		http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
			http://www.springframework.org/schema/tx
			http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
	
	<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
		<property name="configLocation" value="classpath:/hibernate.cfg.xml" /> 
	</bean>
	
	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" /> 
	</bean>
	
	<tx:annotation-driven />
	
</beans>
e coloquei a aplicação pra rodar.. entao surgiram os seguintes erros no console do Eclipse:
16/06/2012 00:50:23 org.apache.catalina.core.StandardContext listenerStart
GRAVE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:341)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:124)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:93)
	at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130)
	at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:467)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:397)
	at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276)
	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4172)
	at org.apache.catalina.core.StandardContext.start(StandardContext.java:4671)
	at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
	at org.apache.catalina.core.StandardHost.start(StandardHost.java:785)
	at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
	at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
	at org.apache.catalina.core.StandardService.start(StandardService.java:525)
	at org.apache.catalina.core.StandardServer.start(StandardServer.java:701)
	at org.apache.catalina.startup.Catalina.start(Catalina.java:585)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
	at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:117)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:328)
	... 27 more

acho que estamos quase lá..
o que ainda falta?

Lucas_Cavalcanti

se o applicationContext.xml estiver no classpath troque a configlocation pra:

<context-param>  
    <param-name>contextConfigLocation</param-name>  
    <param-value>classpath:applicationContext.xml</param-value>  
  </context-param>
tefo

O applicationContext.xml está no classpath sim.
Troquei para essa configuração que você disse e agora está tudo funcionando!!!

Muito obrigado Lucas!!!

Criado 28 de dezembro de 2011
Ultima resposta 16 de jun. de 2012
Respostas 18
Participantes 3