Google App Engine – org.datanucleus.exceptions.NucleusUserException:对象管理器已关闭

为什么下面的代码导致org.datanucleus.exceptions.NucleusUserException:对象管理器已关闭? 似乎在query.getResultList()处抛出exception。

public final void removeUserTokens(final String username) { final Query query = entityManager.createQuery( "SELECT p FROM PersistentLogin p WHERE username = :username"); query.setParameter("username", username); for (Object token : query.getResultList()) { entityManager.remove(token); } } 

例外:

 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:611) at org.datanucleus.store.appengine.query.DatastoreQuery$6.apply(DatastoreQuery.java:610) at org.datanucleus.store.appengine.query.LazyResult.resolveNext(LazyResult.java:94) at org.datanucleus.store.appengine.query.LazyResult$LazyAbstractListIterator.computeNext(LazyResult.java:215) at org.datanucleus.store.appengine.query.AbstractIterator.tryToComputeNext(AbstractIterator.java:132) at org.datanucleus.store.appengine.query.AbstractIterator.hasNext(AbstractIterator.java:127) at org.datanucleus.store.appengine.query.LazyResult$AbstractListIterator.hasNext(LazyResult.java:169) at com.mystuff.service.auth.PersistentTokenRepositoryImpl.removeUserTokens(PersistentTokenRepositoryImpl.java:90) 

编辑 :我增加了datanucleus的日志级别,这就是我所看到的。

 FINE: Object Manager "org.datanucleus.ObjectManagerImpl@5d8d3d6c" opened for datastore "org.datanucleus.store.appengine.DatastoreManager@2447e380" Feb 25, 2010 7:21:38 AM org.datanucleus.ObjectManagerImpl initialiseLevel1Cache FINE: Level 1 Cache of type "weak" initialised Feb 25, 2010 7:21:38 AM org.datanucleus.JDOClassLoaderResolver classForName FINE: Class "java.lang.PersistentLogin" was not found in the CLASSPATH [Class resolver called from org.datanucleus.util.Imports.resolveClassDeclaration (line=177)] Feb 25, 2010 7:21:38 AM org.datanucleus.ObjectManagerImpl disconnectSMCache FINE: Level 1 Cache cleared Feb 25, 2010 7:21:38 AM org.datanucleus.ObjectManagerImpl postClose FINE: Object Manager "org.datanucleus.ObjectManagerImpl@5d8d3d6c" closed Feb 25, 2010 7:21:38 AM com.google.apphosting.utils.jetty.JettyLogger warn WARNING: /j_spring_security_logout 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) 

@Transactional添加到方法可防止对象管理器关闭。 但是,如果没有这个,我不确定为什么会关闭。

我不知道究竟是为什么,但它似乎与延迟加载的query.getResultList() 。 显然,当您调用remove(token)时,延迟加载会中断。

作为一种解决方法,您可以先收集ArrayList中元素的id /键,然后在单独的循环中从数据存储中删除它们吗?

对我有用的解决方案和我在这里找到的bug的描述:

http://groups.google.com/group/google-appengine-java/browse_thread/thread/945f6ca66c1c587e