views:

108

answers:

1

Hi,

I've run into the "can't operate on multiple entity groups in a single transaction." problem when using APPENGINE FOR JAVA w/ JDO with the following code:

PersistenceManager pm = PMF.get().getPersistenceManager();

Query q = pm.newQuery("SELECT this FROM " + TypeA.class.getName() + " WHERE userId == userIdParam "); q.declareParameters("String userIdParam"); List poos = (List) q.execute(userIdParam);

for (TypeA a : allTypeAs) { a.setSomeField(someValue); } pm.close(); }

The problem it seems is that I can't operate on a multiple entities at the same time b/c they arent in the same entity group while in a transaction. Even though it doesn't seem like I'm in a transaction, appengine generates one because I have the following set in my jdoconfig.xml:

   <property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/>

Fine. So far I think I understand.

BUT - if I replace TypeA in the above code, with TypeB - I don't get the error. I don't believe there is anything different between type a and type b - they both have the same key structure. They do have different fields but that shouldn't matter, right?

My question is - what could possible be different between TypeA and TypeB that they give this different behavior? And consequently what do you I fundamentally misunderstand that this behavior could even exist....

Thanks.

+5  A: 

I haven't worked that much with App Engine, but from what I remember an entity group is defined as a hierarchy of objects with a root (tree). If your TypeB objects have a child property that's also a TypeB, it's possible that they're all in the same entity group. Likewise if they're all children to some other type.

If that's not the case you may need to detach the list of objects you get from the select, modify each one, and then create a new transaction for each one to save them one by one.
Take a look at updating using detach (the longer example toward the end of the sub-section).

Andrei Fierbinteanu
TypeB does NOT have any references to any other entities in my datastore. How do you know if your entities are in the same entity group? How do you change that if you want?
aloo
So I made a slight modification to my code. I called pm.detachCopyAll on the results returned by my query. I then iterated through the resulting list making my changes and I finally called pm.MakePersistentAll (followed by a pm.close). This works! BUT WHY?!?!?!?!!?!?
aloo
by works I mean it lets me update multiple TypeA entities at the same time without throwing the original error....
aloo
Well, if you would have a class Book, which has a property `List<Page> pages`, where Page is another class then all the pages of a book would be in the same entity group with that book. I can't really tell why it happens like that for you. I'm not sure that using that JDO option actually means you don't have to create a single transaction; it seems it's more to allow porting of JDO apps that used a different persistence back layer that didn't have some of the limitations of the datastore (which is done by setting it to false in those cases), so I think you should probably use transactions.
Andrei Fierbinteanu