[RESOLVIDO] Duvida: VRaptor3 + GAE + JdoTemplate

11 respostas
von.juliano

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:

11 Respostas

Lucas_Cavalcanti

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

von.juliano

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.

von.juliano
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:
public class JdoTemplateCreator implements ComponentFactory<JdoTemplate> {

	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;
	}
}
O JdoTemplate precisa do PersistenceManagerFactory, o qual consigo sem o Spring. Por fazer dessa forma que esse problema ocorre? Obrigado! :thumbup:
Lucas_Cavalcanti

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

von.juliano

Lucas, fiz da forma que você sugeriu:

applicationContext:
<tx:annotation-driven />

<bean id="pmf" class="org.springframework.orm.jdo.LocalPersistenceManagerFactoryBean">
	<property name="persistenceManagerFactoryName" value="transactions-optional" />
</bean>

<bean id="pmfProxy" class="org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy">
	<property name="targetPersistenceManagerFactory" ref="pmf" />
	<property name="allowCreate" value="true" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.jdo.JdoTransactionManager">
	<property name="persistenceManagerFactory" ref="pmfProxy" />
</bean>
	
<bean id="jdoTemplate" class="org.springframework.orm.jdo.JdoTemplate">
	<property name="persistenceManagerFactory" ref="pmfProxy"></property>
</bean>
Com isso o Spring já injeta o JdoTemplate no meu dao, pelo construtor. Mas, ao buscar alguma coisa, como:
public Cliente busca(String email, String senha) {
		
	List<Cliente> lista = (List<Cliente>) jdoTemplate.find(Cliente.class);
	System.out.println(lista.get(0).getNome());
}
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:
Lucas_Cavalcanti

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

von.juliano

Lucas,

Anotei o método com @Transactional(readOnly = true) e funcionou:
@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());
}
Só fiquei curioso, pq acho que não deveria ter essa necessidade, mas resolveu! :roll:

Obrigado! :thumbup:

Lucas_Cavalcanti

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

von.juliano

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:

Lucas_Cavalcanti

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

von.juliano

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:

Criado 18 de maio de 2010
Ultima resposta 20 de mai. de 2010
Respostas 11
Participantes 2