Maybe I figured it out myself.
I assumed that definition of parent entity was transitive, i.e. if the 
parent of an image is a product and the parent of the product is a shop, 
then shop is ancestor of image, but that is not the case.
So instead of:

Entity variantEntity = new Entity(VariantDBFields.VARIANT_TABLE_NAME, 
KeyFactory.createKey(ProductDBFields.PRODUCT_TABLE_NAME, productId));

variantEntity.setProperty(VariantDBFields.TITLE, variant.getTitle());

...

datastore.put(transaction, variantEntity);


I should do:


Entity variantEntity = new Entity(VariantDBFields.VARIANT_TABLE_NAME, 
KeyFactory.createKey(KeyFactory.createKey(ShopDBFields.SHOP_TABLE_NAME, 
shopId), ProductDBFields.PRODUCT_TABLE_NAME, productId));

variantEntity.setProperty(VariantDBFields.TITLE, variant.getTitle());

...

datastore.put(transaction, variantEntity);


-Louise


Den mandag den 16. januar 2017 kl. 15.33.29 UTC+1 skrev Louise Elmose 
Hedegaard:
>
> My application obviously does not agree that I have only one entity group.
> When I try to insert more than 25 products, I get the error "operating on 
> too many entity groups in a single transaction.".
> When I do not define a XG transaction, I get the error 
> "java.lang.IllegalArgumentException: 
> cross-group transaction need to be explicitly specified, see 
> TransactionOptions.Builder.withXG".
>
> If anybody can provide me with some ideas or hints as to why the above 
> defintions of the entities constitute more than one entity group, I would 
> appreciate it.
>
> Thanks,
> -Louise
>
> Den mandag den 16. januar 2017 kl. 09.45.58 UTC+1 skrev Louise Elmose 
> Hedegaard:
>>
>> Hi Alex,
>>
>> Thank you for answering.
>>
>> Here's how I create the entities:
>>
>> Entity shopEntity = new Entity(ShopDBFields.SHOP_TABLE_NAME);
>> shopEntity.setProperty(ShopDBFields.CREATED, new Date());
>>
>> ....
>> datastore.put(shopEntity);
>>
>>
>>
>> Entity productEntity = new Entity(ProductDBFields.PRODUCT_TABLE_NAME, 
>> KeyFactory.createKey(ShopDBFields.SHOP_TABLE_NAME, shopId));
>> productEntity.setProperty(ProductDBFields.TITLE, product.getTitle());
>>
>> ...
>> datastore.put(transaction, productEntity);
>>
>> (same principle for Settings)
>>
>>
>>
>> Entity variantEntity = new Entity(VariantDBFields.VARIANT_TABLE_NAME, 
>> KeyFactory.createKey(ProductDBFields.PRODUCT_TABLE_NAME, productId));
>>
>> variantEntity.setProperty(VariantDBFields.TITLE, variant.getTitle());
>>
>> ...
>>
>> datastore.put(transaction, variantEntity);
>>
>> (same principle for Option and Image)
>>
>>
>> The flow which eventually leads to the exception (the exact code is 
>> different, but simplified below):
>>
>>
>> DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
>> TransactionOptions options = TransactionOptions.Builder.withXG(true);
>> Transaction transaction = datastore.beginTransaction(options);
>>
>>
>> try {
>> Entity entity = datastore.get(KeyFactory.createKey(ShopDBFields.
>> SHOP_TABLE_NAME, id));
>>
>>      Shop shop = createShop(entity);
>>
>>      <get list of products from web shop API - for each product:>
>>
>> Entity productEntity = new Entity(ProductDBFields.PRODUCT_TABLE_NAME, 
>> KeyFactory.createKey(ShopDBFields.SHOP_TABLE_NAME, shopId));
>>
>>           productEntity.setProperty(ProductDBFields.TITLE, 
>> product.getTitle());
>>
>>           ...
>>           datastore.put(transaction, productEntity);
>>
>>          <for each variant for the given product:> 
>>
>>                Entity variantEntity = new 
>> Entity(VariantDBFields.VARIANT_TABLE_NAME, 
>> KeyFactory.createKey(ProductDBFields.PRODUCT_TABLE_NAME, productId));
>>
>>                variantEntity.setProperty(VariantDBFields.TITLE, 
>> variant.getTitle());
>>
>>                ...
>>
>>                datastore.put(transaction, variantEntity); *<EXCEPTION - 
>> VariantDao.java:45>*
>>
>> logger.info("Initiating commit of transaction");
>> if (transaction.isActive()){
>>
>>         transaction.commit();
>>         logger.info("Transaction comittet");
>>     }else{
>>         logger.warning("Transaction was not active - transaction was not 
>> comittet");
>>     }
>>
>> }
>> finally {
>> if (transaction.isActive()){
>>
>>         transaction.rollback();
>>         logger.info("Transaction rolled back as transaction was still 
>> active");
>>     }else{
>>         logger.info("Transaction was not active - transaction was not 
>> rolledback");
>>     }
>>
>> }
>>
>>
>>
>> The stack trace:
>>
>> /initializeProducts
>> java.lang.IllegalArgumentException: operating on too many entity groups in a 
>> single transaction.
>>      at 
>> com.google.appengine.api.datastore.DatastoreApiHelper.translateError(DatastoreApiHelper.java:50)
>>      at 
>> com.google.appengine.api.datastore.DatastoreApiHelper$1.convertException(DatastoreApiHelper.java:121)
>>      at 
>> com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:97)
>>      at 
>> com.google.appengine.api.datastore.Batcher$ReorderingMultiFuture.get(Batcher.java:131)
>>      at 
>> com.google.appengine.api.datastore.FutureHelper$TxnAwareFuture.get(FutureHelper.java:182)
>>      at 
>> com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:89)
>>      at 
>> com.google.appengine.api.datastore.FutureHelper.getInternal(FutureHelper.java:76)
>>      at 
>> com.google.appengine.api.datastore.FutureHelper.quietGet(FutureHelper.java:36)
>>      at 
>> com.google.appengine.api.datastore.DatastoreServiceImpl.put(DatastoreServiceImpl.java:61)
>>      at 
>> dk.elmose.apps.shopify.stocksniffer.dao.VariantDao.create(VariantDao.java:45 
>> <https://console.cloud.google.com/debug/fromlog?appModule=default&appVersion=1&file=dk%2Felmose%2Fapps%2Fshopify%2Fstocksniffer%2Fdao%2FVariantDao.java&line=45&logInsertId=5878c85300027265264c2be5&logNanos=1484310605117867000&nestedLogIndex=6&project=elmose-stocksniffer>)
>>
>>
>>
>> Den fredag den 13. januar 2017 kl. 23.41.35 UTC+1 skrev Alex (Cloud 
>> Platform Support):
>>>
>>> Hi Louise,
>>>
>>> You’re right, as stated per the Transactions and Entity Groups 
>>> documentation 
>>> <https://cloud.google.com/datastore/docs/concepts/transactions#transactions_and_entity_groups>,
>>>  
>>> there is a 25 entity groups limit for a single data transaction. However, 
>>> according to your description this error should not happen and there should 
>>> be no need of using Cross-Group (XG) Transactions either. Still, it is 
>>> possible that this error is triggered by something else as the way your 
>>> entities were defined.
>>>
>>> Can you provide a Minimal Working Example 
>>> <https://en.wikipedia.org/wiki/Minimal_Working_Example> of your code 
>>> including the transaction and a snippet of how you defined your entities? 
>>> In fact, this would help to better visualize the root cause of your error 
>>> and provide you with answer on how to solve it.
>>>
>>> Regards,
>>> Alex
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/google-appengine.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/google-appengine/bbcc0727-9e8e-4218-ab56-adae92167347%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to