Hi,
When saving an entity with an unowned relationship, GAE seems to dislike to 
persist this composite entity when the pm.makeperistent(object) call is 
triggered from within a beginTxn() commitTxn().
I am using  datanucleus-appengine-2.0.1.jar with JDO.

Summary entities used in the test case:
(1) Entity CashFlowCategory is independent and has its own entity group
(2) Entity User is idependent an has its own entity group
(3) Entity CashFlow belongs to the user's entity group (part of a user's 
hierarchy of objects), and, additionally, it is also composed by an *Unowned
* relationship with CashFlowCategory because, as stated in (1), Cashflow is 
an different entity group other than CashflowCategory. The 
CashflowCategory, evidently, is an entity that has no knowledge of teh 
CashFlow entities. So it is an unowned unidirectional relationship.


Summary of the testcase:
In the test that is blowing a apart several begin() commit() transactions 
are triggered, always saving data in no more than one entity group at a 
time.
Let's say that we reach a point in time where User and CashflowCategories 
are already persisted and that is time to create a new object of type 
CashFlow.
By creating this object and properly linking it in the hierarchy that it 
belongs to we should only be modifying the User entity group. The cashflow 
goes in the User's descedents hierarchy, on the other hand the 
CashflowCategory entity group continues blind as to teh fact that a 
Cashflow entity referencing it.
In particular, the cashflow is added to a cointainer belonging to the User 
Entity Group.
Outcomes of test:
(1) If I simply issue the pm.makePersitent(cashflow); 
My test is successful.

(2) If instead I do beginTxn(pm); pm.makePersitent(cashflow); 
 commitTxn(pm);
Then  GAE rejects the transaction by stating that I am trying to make 
changes to the User and Cashflowcategory entity groups, which should be 
false.
In fact, I can for example see in the GAE admin page that the cashflow 
entity is correctly saved when I just trigger the makepersistent() call on 
the cashflow  while not enclosing it in a transaction.

Is this a known issue, or am I not seeing the whole picture correctly?




javax.jdo.JDOException: can't operate on multiple entity groups in a single 
transaction.found both Element {
  type: "CashFlowCategory"
  id: 1
}
 and Element {
  type: "User"
  id: 3
}

at 
org.datanucleus.api.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:567)
at org.datanucleus.api.jdo.JDOTransaction.commit(JDOTransaction.java:163)
at 
pt.ninetyninesono.expenses.model.entities.SaveUserWithCashFlowDataTest$1MethodImplementation.commitTxn(SaveUserWithCashFlowDataTest.java:208)
at 
pt.ninetyninesono.expenses.model.entities.SaveUserWithCashFlowDataTest$1MethodImplementation.execute(SaveUserWithCashFlowDataTest.java:250)
at 
pt.ninetyninesono.expenses.model.entities.SaveUserWithCashFlowDataTest.testCreateUserWithCashFlowDataSimpleImpl(SaveUserWithCashFlowDataTest.java:262)
at 
pt.ninetyninesono.expenses.model.entities.SaveUserWithCashFlowDataTest.testCreateUserWithCashFlowDataSimple(SaveUserWithCashFlowDataTest.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:243)
at junit.framework.TestSuite.run(TestSuite.java:238)
at 
org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at 
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at 
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
NestedThrowablesStackTrace:
java.lang.IllegalArgumentException: can't operate on multiple entity groups 
in a single transaction.found both Element {
  type: "CashFlowCategory"
  id: 1
}
 and Element {
  type: "User"
  id: 3
}

at 
com.google.appengine.api.datastore.DatastoreApiHelper.translateError(DatastoreApiHelper.java:36)
at 
com.google.appengine.api.datastore.DatastoreApiHelper$1.convertException(DatastoreApiHelper.java:76)
at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:106)
at 
com.google.appengine.api.datastore.FutureHelper$CumulativeAggregateFuture.get(FutureHelper.java:145)
at 
com.google.appengine.api.datastore.FutureHelper$TxnAwareFuture.get(FutureHelper.java:222)
at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:90)
at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:90)
at 
com.google.appengine.api.datastore.FutureHelper.getInternal(FutureHelper.java:72)
at 
com.google.appengine.api.datastore.FutureHelper.quietGet(FutureHelper.java:59)
at 
com.google.appengine.api.datastore.DatastoreServiceImpl.get(DatastoreServiceImpl.java:55)
at 
com.google.appengine.datanucleus.WrappedDatastoreService.get(WrappedDatastoreService.java:70)
at 
com.google.appengine.datanucleus.EntityUtils.getEntityFromDatastore(EntityUtils.java:665)
at 
com.google.appengine.datanucleus.DatastorePersistenceHandler.updateObject(DatastorePersistenceHandler.java:419)
at org.datanucleus.state.JDOStateManager.flush(JDOStateManager.java:3874)
at 
org.datanucleus.ObjectManagerImpl.flushInternalWithOrdering(ObjectManagerImpl.java:3797)
at 
org.datanucleus.ObjectManagerImpl.flushInternal(ObjectManagerImpl.java:3720)
at org.datanucleus.ObjectManagerImpl.flush(ObjectManagerImpl.java:3666)
at org.datanucleus.ObjectManagerImpl.preCommit(ObjectManagerImpl.java:4050)
at 
org.datanucleus.ObjectManagerImpl$2.transactionPreCommit(ObjectManagerImpl.java:398)
at 
org.datanucleus.TransactionImpl.internalPreCommit(TransactionImpl.java:370)
at org.datanucleus.TransactionImpl.commit(TransactionImpl.java:259)
at org.datanucleus.api.jdo.JDOTransaction.commit(JDOTransaction.java:96)
at 
pt.ninetyninesono.expenses.model.entities.SaveUserWithCashFlowDataTest$1MethodImplementation.commitTxn(SaveUserWithCashFlowDataTest.java:208)
at 
pt.ninetyninesono.expenses.model.entities.SaveUserWithCashFlowDataTest$1MethodImplementation.execute(SaveUserWithCashFlowDataTest.java:250)
at 
pt.ninetyninesono.expenses.model.entities.SaveUserWithCashFlowDataTest.testCreateUserWithCashFlowDataSimpleImpl(SaveUserWithCashFlowDataTest.java:262)
at 
pt.ninetyninesono.expenses.model.entities.SaveUserWithCashFlowDataTest.testCreateUserWithCashFlowDataSimple(SaveUserWithCashFlowDataTest.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:243)
at junit.framework.TestSuite.run(TestSuite.java:238)
at 
org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at 
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at 
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)


-- 
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/google-appengine/-/fa4i30IupQgJ.
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?hl=en.

Reply via email to