Transactions are failing with "java.lang.IllegalArgumentException: transactions on multiple entity groups only allowed in High Replication applications"

211 views
Skip to first unread message

Miroslav Genov

unread,
Jun 13, 2012, 9:23:27 AM6/13/12
to twig-p...@googlegroups.com
Hello,

I'm getting a strange exception that shows that multiple entity groups are used when I'm trying to save only a single entity in a transaction. Here is a sample test that shows what I'm exactly doing:

public class TransactionTest extends LocalDatastoreTestCase {

  static class Foo {
    @Id
    public Long id;
  }

  @Test
  public void storeEntityInTransaction() {
    ObjectDatastore datastore = new AnnotationObjectDatastore(false);
    Foo foo = new Foo();

    datastore.beginTransaction();

    datastore.store(foo);

    assertThat(foo.id,is(not(nullValue())));

    datastore.getTransaction().commit();
  }

}

Here is the full stack trace that is shown from the execution:
INFO: Local Datastore initialized: 
Type: Master/Slave
Storage: In-memory

java.lang.IllegalArgumentException: transactions on multiple entity groups only allowed in High Replication applications
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.getInternal(FutureHelper.java:72)
at com.google.appengine.api.datastore.FutureHelper.quietGet(FutureHelper.java:33)
at com.google.appengine.api.datastore.TransactionImpl.getHandle(TransactionImpl.java:97)
at com.google.appengine.api.datastore.TransactionImpl.getId(TransactionImpl.java:206)
at com.google.appengine.api.datastore.BaseDatastoreServiceImpl.localTxnToRemoteTxn(BaseDatastoreServiceImpl.java:116)
at com.google.appengine.api.datastore.AsyncDatastoreServiceImpl.doBatchPutBySize(AsyncDatastoreServiceImpl.java:516)
at com.google.appengine.api.datastore.AsyncDatastoreServiceImpl.put(AsyncDatastoreServiceImpl.java:485)
at com.google.appengine.api.datastore.AsyncDatastoreServiceImpl.put(AsyncDatastoreServiceImpl.java:439)
at com.google.appengine.api.datastore.DatastoreServiceImpl.put(DatastoreServiceImpl.java:101)
at com.google.code.twig.standard.BaseObjectDatastore.singlePutWithTransaction(BaseObjectDatastore.java:301)
at com.google.code.twig.standard.BaseObjectDatastore.servicePut(BaseObjectDatastore.java:266)
at com.google.code.twig.standard.StandardCommonStoreCommand.instanceToKey(StandardCommonStoreCommand.java:260)
at com.google.code.twig.standard.StandardSingleStoreCommand.now(StandardSingleStoreCommand.java:43)
at com.google.code.twig.standard.TranslatorObjectDatastore.store(TranslatorObjectDatastore.java:182)
at com.google.code.twig.TransactionTest.storeEntityInTransaction(TransactionTest.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 org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.junit.runner.JUnitCore.run(JUnitCore.java:130)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)


Miroslav Genov

unread,
Jun 13, 2012, 9:25:50 AM6/13/12
to twig-p...@googlegroups.com
Just made a change in the test that uses store().type() and it seems that the result is same. Here is the snippet from my last try:

  @Test
  public void storeEntityInTransaction() {
    ObjectDatastore datastore = new AnnotationObjectDatastore(false);
    Foo foo = new Foo();

    datastore.beginTransaction();

    datastore.store().instance(foo).now();

    assertThat(foo.id,is(not(nullValue())));

    datastore.getTransaction().commit();

Miroslav Genov

unread,
Jun 13, 2012, 9:46:45 AM6/13/12
to twig-p...@googlegroups.com
Ah I found it. It seems that the default Settings is enabling cross group transactions, where these transactions could only be used in Multimaster datastore. With a new settings that disables cross group transaction everything is working like e charm. 

John Patterson

unread,
Jun 13, 2012, 11:22:20 PM6/13/12
to twig-p...@googlegroups.com
Ah nice one.  Yes I found the same thing recently during a test case that used Master / Slave.
Reply all
Reply to author
Forward
0 new messages