[RESOLVIDO] Duvida: VRaptor3 + GAE + JdoTemplate

Boa tarde galera!

Tenho um projeto com VRaptor 3 no Google App Engine, e estou usando alguns componentes do Spring, mas estou com problemas com o JdoTemplate. Criei a ComponentFactory adequada, e utilizando o PersistenceManager funciona, mas para o JdoTemplate ainda estou pesquisando a razão do problema. Segue a exception gerada:

br.com.caelum.vraptor.InterceptionException: an exception was raised while executing resource method at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:86) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:77) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42) at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.p2j.site.util.jdo.JdoTransactionInterceptor.intercept(JdoTransactionInterceptor.java:33) at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:46) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:81) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70) at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92) at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56) at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:51) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:122) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418) at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:70) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:349) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) at org.mortbay.jetty.Server.handle(Server.java:326) at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923) at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:547) at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409) at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582) Caused by: org.datanucleus.exceptions.NucleusUserException: Object Manager has been closed at org.datanucleus.ObjectManagerImpl.assertIsOpen(ObjectManagerImpl.java:3876) at org.datanucleus.ObjectManagerImpl.getFetchPlan(ObjectManagerImpl.java:376) at org.datanucleus.store.query.Query.getFetchPlan(Query.java:497) at org.datanucleus.store.appengine.query.DatastoreQuery$6.apply(DatastoreQuery.java:631) at org.datanucleus.store.appengine.query.DatastoreQuery$6.apply(DatastoreQuery.java:630) at org.datanucleus.store.appengine.query.LazyResult.resolveNext(LazyResult.java:94) at org.datanucleus.store.appengine.query.LazyResult.resolveAll(LazyResult.java:116) at org.datanucleus.store.appengine.query.LazyResult.size(LazyResult.java:110) at org.datanucleus.store.appengine.query.StreamingQueryResult.size(StreamingQueryResult.java:124) at br.com.p2j.site.dao.jdo.JdoImovelDao.busca(JdoImovelDao.java:46) at br.com.p2j.site.controller.ImovelController.home(ImovelController.java:29) 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 com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:100) at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:57) ... 52 more Qualquer sugestão é bem vinda! Obrigado! :thumbup:

vc tá usando o template fora de transações?

Oi Lucas,

Sim, na verdade, só testei seu uso para buscas simples, como

List<Cliente> lista = (List<Cliente>) jdoTemplate.find(Cliente.class); e em qualquer situação tomo esse erro.

Estava lendo sobre a integração entre VRaptor e Spring, e li que para usar os componentes do Spring eu preciso do applicationContext.xml e configurar lá os componentes. No meu sistema tentei prover o JdoTemplate da seguinte forma:

[code]public class JdoTemplateCreator implements ComponentFactory {

private final PersistenceManagerFactory factory;
private JdoTemplate template;

public JdoTemplateCreator(PersistenceManagerFactory factory) {
	this.factory = factory;
}

@PostConstruct
public void create() {
	template = new JdoTemplate(factory);
}

public JdoTemplate getInstance() {
	return template;
}

}[/code]O JdoTemplate precisa do PersistenceManagerFactory, o qual consigo sem o Spring. Por fazer dessa forma que esse problema ocorre?
Obrigado! :thumbup:

pq o spring controla várias coisas usando estruturas internas dele, então se vc não usar o jeito dele de criar as classes, ele pode não configurar alguma coisa…

tenta usar o jdotemplate do jeito do spring, configurando no applicationContext.xml que provavelmente vai funcionar

Lucas, fiz da forma que você sugeriu:

applicationContext:

[code]<tx:annotation-driven />

[/code]Com isso o Spring já injeta o JdoTemplate no meu dao, pelo construtor. Mas, ao buscar alguma coisa, como: [code]public Cliente busca(String email, String senha) {
List<Cliente> lista = (List<Cliente>) jdoTemplate.find(Cliente.class);
System.out.println(lista.get(0).getNome());

}[/code]Isso gera a seguinte exceção:Object Manager has been closed org.datanucleus.exceptions.NucleusUserException: Object Manager has been closed at org.datanucleus.ObjectManagerImpl.assertIsOpen(ObjectManagerImpl.java:3876) at org.datanucleus.ObjectManagerImpl.getFetchPlan(ObjectManagerImpl.java:376) at org.datanucleus.store.query.Query.getFetchPlan(Query.java:497) at org.datanucleus.store.appengine.query.DatastoreQuery$6.apply(DatastoreQuery.java:631) at org.datanucleus.store.appengine.query.DatastoreQuery$6.apply(DatastoreQuery.java:630) at org.datanucleus.store.appengine.query.LazyResult.resolveNext(LazyResult.java:94) at org.datanucleus.store.appengine.query.LazyResult.get(LazyResult.java:81) at org.datanucleus.store.appengine.query.StreamingQueryResult.get(StreamingQueryResult.java:101) at br.com.p2j.webexpoimoveis.dao.jdo.JdoClienteDao.busca(JdoClienteDao.java:41) at br.com.p2j.webexpoimoveis.controller.HomeController.login(HomeController.java:45) 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 com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:100) at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:57) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:77) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42) at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:46) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:81) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65) at br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70) at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92) at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56) at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:51) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:122) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418) at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:70) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:349) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) at org.mortbay.jetty.Server.handle(Server.java:326) at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938) at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755) at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409) at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)Sabe o qual pode ser a razão do problema? Vlw! :thumbup:

tenta usar esse filtro:
http://static.springsource.org/spring/docs/1.1.x/api/org/springframework/orm/jdo/support/OpenPersistenceManagerInViewFilter.html

Lucas,

Anotei o método com @Transactional(readOnly = true) e funcionou:

[code] @Transactional(readOnly = true)
public Cliente busca(String email, String senha) {

List<Cliente> lista = (List<Cliente>) jdoTemplate.find(Cliente.class);
System.out.println(lista.get(0).getNome());

}[/code]Só fiquei curioso, pq acho que não deveria ter essa necessidade, mas resolveu! :roll:

Obrigado! :thumbup:

verdade, tinha esquecido disso :stuck_out_tongue:

o template só funciona dentro de uma transação…
pq senão o spring não sabe qdo abrir e fechar o object manager

Acho que tô muito acostumado com o Spring gerenciando tudo por mim, e esqueci que usando outras ferramentas às vezes é necessário fazer coisas assim eu mesmo!

Muito obrigado pela ajuda! :mrgreen:

mesmo se vc usasse spring puro vc precisaria colocar a chamada ao jdoTemplate dentro de uma transação… ou com @Transactional ou com o Open*InViewFilter… mesma coisa pra JPA ou Hibernate

Aqui temos um projeto com Spring + Hibernate em que nas classes Dao não é usada a anotação @Transactional,nem o Open*…, apenas a configuração que injeta o hibernateTemplate nos Daos. Lembro de ter lido, acho que no Spring in Action, que as classes Daos, quando recebem o template, ou quando herdam de DaoSupport, seus métodos passam a ser transacionais.

Vou procurar, se achar posto aqui! :smiley: