I have the same exception with my app.
Here is my code:
PersistenceManager pm = PMF.get().getPersistenceManager();
Query query = this.pm.newQuery("select key from " +
Subscription.class.getName()
+ " where nextMail <= :dateParam && status ==
:statusParam");
List<Key> keys = (List<Key>) query.execute(new Date(), 1);
for (Key key: keys) {
Queue queue = QueueFactory.getDefaultQueue();
TaskOptions task = url('handler');
task.param('key', KeyFactory.keyToString(key));
queue.add(task);
}
pm.close();
This throws the exception during pm.close() :
NestedThrowablesStackTrace:
java.lang.IllegalArgumentException: can't operate on multiple entity
groups in a single transaction.
at
com.google.appengine.api.datastore.DatastoreApiHelper.translateError(DatastoreApiHelper.java:
34)
at
com.google.appengine.api.datastore.DatastoreApiHelper.makeSyncCall(DatastoreApiHelper.java:
67)
at com.google.appengine.api.datastore.DatastoreServiceImpl
$1.run(DatastoreServiceImpl.java:128)
at
com.google.appengine.api.datastore.TransactionRunner.runInTransaction(TransactionRunner.java:
30)
at
com.google.appengine.api.datastore.DatastoreServiceImpl.get(DatastoreServiceImpl.java:
111)
at
com.google.appengine.api.datastore.DatastoreServiceImpl.get(DatastoreServiceImpl.java:
84)
at
com.google.appengine.api.datastore.DatastoreServiceImpl.get(DatastoreServiceImpl.java:
72)
at
org.datanucleus.store.appengine.RuntimeExceptionWrappingDatastoreService.get(RuntimeExceptionWrappingDatastoreService.java:
63)
at
org.datanucleus.store.appengine.DatastorePersistenceHandler.get(DatastorePersistenceHandler.java:
96)
at
org.datanucleus.store.appengine.DatastorePersistenceHandler.get(DatastorePersistenceHandler.java:
106)
at
org.datanucleus.store.appengine.DatastorePersistenceHandler.fetchObject(DatastorePersistenceHandler.java:
478)
at
org.datanucleus.state.JDOStateManagerImpl.loadUnloadedFieldsInFetchPlan(JDOStateManagerImpl.java:
1627)
at
org.datanucleus.state.JDOStateManagerImpl.detach(JDOStateManagerImpl.java:
3560)
at
org.datanucleus.ObjectManagerImpl.performDetachOnClose(ObjectManagerImpl.java:
3270)
at org.datanucleus.ObjectManagerImpl.close(ObjectManagerImpl.java:
807)
at
org.datanucleus.jdo.JDOPersistenceManager.close(JDOPersistenceManager.java:
271)
The only thing I can think of is that PMF.get() is being recycled from
a previous request, and somehow it is in a bad state. But the doc
clearly says that we should recycle this object. What is going on ?
On Jun 8, 9:05 am, JD <[email protected]> wrote:
> I am not using atransaction(see original POST), which is the
> problem.
>
> On Jun 4, 11:03 am, Chau Huynh <[email protected]> wrote:
>
>
>
> > Did you have different entity groups inside atransaction?
> > Google have a constraint of what can be done in
> > atransactionherehttp://code.google.com/appengine/docs/python/datastore/transactions.h...
>
> > On Fri, Jun 4, 2010 at 5:45 PM, JD <[email protected]> wrote:
> > > After debugging, I was able to get rid of the exception by removing a
> > > pm.newQuery() which was happening on a different entity group.
>
> > > To me this is a bug in App Engine, as there is no reason the query on
> > > a particular entity group should fail outside atransaction.
>
> > > On Jun 3, 12:25 pm, Millisecond <[email protected]> wrote:
> > > > Hmmm.
>
> > > > How is your object model structured? Do entities have other entities
> > > > as direct references?
>
> > > > If you have "class A { B b }" and setting b to an instance of B that
> > > > already existed might throw the error you're seeing.
>
> > > > I changed my structure to be "class A { String bKey }" for a variety
> > > > of other reasons, but guess it also may have gotten around this
> > > > problem.
>
> > > > Alternatively, post as much code as you can and I'll see if anything
> > > > else rings a bell, early on I spent a frustrated day or two working
> > > > around this exception in a variety of places so know it can be
> > > > frustrating.
>
> > > > -C
>
> > > > On Jun 3, 6:33 am, JD <[email protected]> wrote:
>
> > > > > I added a call to flush() after every change on the PM-managed object,
> > > > > but that did not help.
>
> > > > > Also doing a pm.flush() does not throw this exception, but doing a
> > > > > pm.close() does - which seems to be contrary to your reasoning (I
> > > > > would expect flush to throw the same exception if multiple entity
> > > > > groups were at cause).
>
> > > > > On Jun 3, 1:33 am, Millisecond <[email protected]> wrote:
>
> > > > > > Even though you're not using transactions, I think it's trying to
> > > make
> > > > > > the .close() call atomic (maybe with an internal implicit
> > > > > >transaction), failing or succeeding as a whole. And as I understand
> > > > > > it, entities not in the same group can be stored on separate
> > > > > > machines
> > > > > > so can't be operated on atomically.
>
> > > > > > I've worked around this by calling a flush() after most any change
> > > > > > on
> > > > > > a PM-managed object until close(). If this has a huge number of
> > > reqs/
> > > > > > s, you may want to re-architect to get the objects in the same
> > > > > > entity
> > > > > > group as multiple flushes won't be very efficient.
>
> > > > > > -C
>
> > > > > > On Jun 2, 8:26 pm, JD <[email protected]> wrote:
>
> > > > > > > I have a PersistenceManager
>
> > > > > > > PersistenceManager pm = PMF.get().getPersistenceManager();
>
> > > > > > > which I use to do a bunch of operations on different objects, but
> > > > > > > WITHOUTtransaction(run queries, store entities and lookup
> > > entities).
>
> > > > > > > I then close the manager with pm.close() and get this obscure
> > > > > > > error
> > > > > > > that complains about multiple entity groups inside atransaction
> > > even
> > > > > > > though I am not using atransaction(you will notice that the error
> > > is
> > > > > > > not the usual one where it prints the different entity groups).
>
> > > > > > > I am not 100% confident but have the impression that this error
> > > > > > > started happening with the 1.3.4 release.
> > > > > > > 100% reproducible use case. Would appreciate input from App Engine
> > > > > > > developers.
>
> > > > > > > com.myapp.servlet.task.PopulateUserPages doAction: Illegal
> > > > > > > argument
> > > > > > > javax.jdo.JDOFatalUserException: Illegal argument
> > > > > > > at
>
> > > org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(Nuc
> > > leusJDOHelper.java:
> > > > > > > 344)
> > > > > > > at
>
> > > org.datanucleus.jdo.JDOPersistenceManager.close(JDOPersistenceManager.java:
> > > > > > > 281)
> > > > > > > at
> > > com.myapp.dao.jdo.DatastoreService.release(DatastoreService.java:
> > > > > > > 631)
> > > > > > > at
>
> > > com.myapp.servlet.AbstractBaseServlet.releaseService(AbstractBaseServlet.ja
> > > va:
> > > > > > > 243)
> > > > > > > at
>
> > > com.myapp.servlet.task.PopulateUserPages.doAction(PopulateUserPages.java:
> > > > > > > 132)
> > > > > > > at
> > > com.myapp.servlet.task.Dispatcher.doAction(Dispatcher.java:35)
> > > > > > > at
> > > com.myapp.servlet.task.TaskServlet.doAction(TaskServlet.java:36)
> > > > > > > at
>
> > > com.myapp.servlet.AbstractBaseServlet.doGenericAction(AbstractBaseServlet.j
> > > ava:
> > > > > > > 194)
> > > > > > > at
>
> > > com.myapp.servlet.AbstractBaseServlet.doPost(AbstractBaseServlet.java:
> > > > > > > 84)
> > > > > > > at
> > > javax.servlet.http.HttpServlet.service(HttpServlet.java:713)
> > > > > > > at
> > > javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
> > > > > > > at
> > > org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:
> > > > > > > 511)
> > > > > > > at org.mortbay.jetty.servlet.ServletHandler
> > > > > > > $CachedChain.doFilter(ServletHandler.java:1166)
> > > > > > > at
>
> > > com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlo
> > > bUploadFilter.java:
> > > > > > > 97)
> > > > > > > at org.mortbay.jetty.servlet.ServletHandler
> > > > > > > $CachedChain.doFilter(ServletHandler.java:1157)
> > > > > > > at
>
> > > com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionF
> > > ilter.java:
> > > > > > > 35)
> > > > > > > at org.mortbay.jetty.servlet.ServletHandler
> > > > > > > $CachedChain.doFilter(ServletHandler.java:1157)
> > > > > > > at
>
> > > com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(Trans
> > > actionCleanupFilter.java:
> > > > > > > 43)
> > > > > > > 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.runtime.jetty.AppVersionHandlerMap.handle(AppVersionH
> > > andlerMap.java:
> > > > > > > 238)
> > > > > > > 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
>
> > > com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequ
> > > estParser.java:
> > > > > > > 76)
> > > > > > > at
> > > org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
> > > > > > > at
>
> > > com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceReques
> > > t(JettyServletEngineAdapter.java:
> > > > > > > 135)
> > > > > > > at
>
> > > com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:
> > > > > > > 250)
> > > > > > > at com.google.apphosting.base.RuntimePb$EvaluationRuntime
> > > > > > > $6.handleBlockingRequest(RuntimePb.java:5838)
> > > > > > > at com.google.apphosting.base.RuntimePb$EvaluationRuntime
> > > > > > > $6.handleBlockingRequest(RuntimePb.java:5836)
> > > > > > > at
>
> > > com.google.net.rpc.impl.BlockingApplicationHandler.handleRequest(BlockingAp
> > > plicationHandler.java:
> > > > > > > 24)
> > > > > > > at
> > > com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:
> > > > > > > 398)
> > > > > > > at com.google.net.rpc.impl.Server$2.run(Server.java:852)
> > > > > > > at
>
> > > com.google.tracing.LocalTraceSpanRunnable.run(LocalTraceSpanRunnable.java:
> > > > > > > 56)
> > > > > > > at
>
> > > com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpa
> > > nBuilder.java:
> > > > > > > 576)
> > > > > > > at
> > > > > > > com.google.net.rpc.impl.Server.startRpc(Server.java:807)
> > > > > > > at
> > > com.google.net.rpc.impl.Server.processRequest(Server.java:369)
> > > > > > > at
>
> > > com.google.net.rpc.impl.ServerConnection.messageReceived(ServerConnection.j
> > > ava:
> > > > > > > 442)
> > > > > > > at
>
> > > com.google.net.rpc.impl.RpcConnection.parseMessages(RpcConnection.java:
> > > > > > > 319)
> > > > > > > at
>
> > > com.google.net.rpc.impl.RpcConnection.dataReceived(RpcConnection.java:
> > > > > > > 290)
> > > > > > > at
> > > com.google.net.async.Connection.handleReadEvent(Connection.java:
> > > > > > > 474)
> > > > > > > at
>
> > > com.google.net.async.EventDispatcher.processNetworkEvents(EventDispatcher.j
> > > ava:
> > > > > > > 831)
> > > > > > > at
>
> > > com.google.net.async.EventDispatcher.internalLoop(EventDispatcher.java:
> > > > > > > 207)
> > > > > > > at
> > > com.google.net.async.EventDispatcher.loop(EventDispatcher.java:
> > > > > > > 103)
> > > > > > > at
>
> > > com.google.net.rpc.RpcService.runUntilServerShutdown(RpcService.java:
>
> ...
>
> read more »
--
You received this message because you are subscribed to the Google Groups
"Google App Engine for Java" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-appengine-java?hl=en.