Entity not queried immediately after commit in data nucleus JPA - google-app-engine

I am using Data Nucleus JPA for persistence in my GWT application. my persist API in Entity looks like this:
EntityManager em = EMF.getEM();
try {
em.getTransaction().begin();
if(!em.contains(this)){
em.persist(this);
em.flush();
}
em.getTransaction().commit();
} finally {
em.close();
}
I am following this document: http://www.datanucleus.org/products/datanucleus/jpa/transactions.html#local
This code works fine and commits data. But when I query the committed record immediately after commit, sometimes entity is not queried. If I query after after few seconds, it is queried. Please note that this issue is intermittent.
Any hints/suggestions what could be the cause of this intermittent issue?
Thanks

Suggest you do a Google search for "eventual consistency" and read the GAE docs, since it mentions this concept

This page talks about Strcuturing for Strong consistency and it solved the problem for me. https://developers.google.com/appengine/docs/java/datastore/structuring_for_strong_consistency
Basically including ancestor definition in your query e.g,
Query query = new Query("Entity").setAncestor(ancestorKey).setFilter(filter);

Related

GAE console updates not applying to deployed app (not eventual consistency)

My app is GAE standard.
I can edit an entity in the cloud console from a URL that starts with this:
https://console.cloud.google.com/datastore/entities/query
I'll save the entity and refresh the page and the new data is shown.
On my website, I then go to a page that retrieves the entity using the entity ID like this
e = Entity.get_by_id(1234)
But my website shows the old data! It seems like this shouldn't be possible.
My only solution is to then use remote api shell to get the entity (which shows the old data) and then update and then put the entity. My website then shows the new data.
How is it possible that updating an entity in the cloud console doesn't show up in production when getting an entity by its id?
Try something like this:
e = Entity.get_by_id(1234, use_cache=False, use_memcache=False)
or
the_key = ndb.Key(Entity, 12345)
the_key.get(use_cache=False, use_memcache=False)
There are other params you can set, like memcache_timeout and read_policy:
https://cloud.google.com/appengine/docs/standard/python/ndb/functions#context_options
This sounds like a caching problem - as the warning at the top of this page notes, updating entities via the datastore console doesn't update or flush the cache. You should try flushing the memcache via the console after you make an update, which will ensure that the query hits the datastore directly.

Google Appengine Datastore filter and sort direction together

I am trying to use the below SQL query in datastore
Select *from users where catagory="A" ODER BY id.
I tried the below code
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
Filter filter=new FilterPredicate("catagory", FilterOperator.EQUAL, "A");
Query q = new Query("users");
q.setFilter(filter);
q.addSort("id", SortDirection.DESCENDING);
The setfilter() and addsort() functions are not working together. Any suggestion will be appreciated.
From Class DatastoreNeedIndexException:
DatastoreNeedIndexException is thrown when no matching index was
found for a query requiring an index. Check the Indexes page in the
Admin Console and your datastore-indexes.xml file.
In many cases the development server creates the necessary indexes automatically when your app requires them. See Creating indexes using the development server.
But in some cases the automatic index updates don't happen. In such cases you need to create/update the indexes manually. See Creating indexes manually.
Updating the indexes on GAE also happens most of the time automatically, when the app code is deployed, but occasionally they need to be updated manually. From Updating indexes:
./appengine-java-sdk/bin/appcfg.sh update_indexes myapp/war
After the GAE indexes are updated it may take a while for them to get in serving state. Until that state is reached the same error can be seen. Check the status of the app's indexes in the developer's console. Also mentioned in Updating indexes.

Google App Engine Entity Manager retrieving old value

Using GAE, I am using javax's entity manager (javax.persistence.EntityManagerFactory) to generate an instance of the entity manager:
private static final EntityManagerFactory emfInstance = Persistence.createEntityManagerFactory("transactions-optional");
I retrieve from the datastore using the following code:
event = mgr.find(Event.class, id);
The problem I have is that if I retrieve the data for the first time, everything goes fine. However, if I go through the "Datastore Viewer" in the GAE dashboard to edit the values manually. The next time I call the data, using the "find" method, the values returned are the old value. I have to manually upload backend again in order to get the new values.
Any idea what is causing this? I would like mgr.find to always call the latest value. Thanks.
The entity is being cached. When you change it through the Datastore Viewer, the entity cached by your backend is not affected.
After you make a change in the Datastore viewer, click on the "Flush Memcache" button.
If this does not help, you may need to change configuration for your caching:
Level2 Caching is enabled by default. To get the previous default
behavior, set the persistence property datanucleus.cache.level2.type
to none. (Alternatively include the datanucleus-cache plugin in the
classpath, and set the persistence property
datanucleus.cache.level2.type to javax.cache to use Memcache for L2
caching.
Try flushing memcache and then try your query again.Most times the last persisted entity data is what's retrieved until you do this.

Update query using JPA and Google App Engine

I'm trying to update my entity class, but I am getting :
javax.persistence.PersistenceException: Only select and delete statements are supported.
this exact code worked fine when i wasn't using Google app engine.
My code is:
em.getTransaction().begin();
Query query =
em.createQuery("UPDATE Profile p" +
"SET p.age = 1 " +
"WHERE p.email = :email" );
query.setParameter("newPoint", point);
query.setParameter("email", email);
int updateCount = query.executeUpdate();
em.getTransaction().commit();
So I'm asking how can I update the entity query?
Since the GAE datastore doesn't support a query that updates fields in the datastore directly, then you similarly cannot do that via the JPA API. Since JPA was never designed for other types of datastores then you will see features that are inapplicable.
Retrieve the objects via query, and update them manually.
When GAE provides full map-reduce out-of-the-box then something like that would be viable to support

Grails: updating hibernate after externally loading data

I have a grails application. I'd like to load data into the underlying database with something external to grails, perl, specifically. I know I have to update the hibernate sequence after external data loading, otherwise on the next create object in grails, hibernate throws an exception; but is there anything else I need to update? Do I have to clear the hibernate cache, for instance? This would seem to be a very common issue, but there's no discussion of it in the grails docs. Thanks.
Found this
http://grails.1312388.n4.nabble.com/Accessing-the-2nd-level-cache-to-allow-it-to-be-cleared-via-a-controller-or-service-td1390985.html
Hibernate has APIs for this. You can get the query cache via sessionFactory.getQueryCache() and clear it using
sessionFactory.queryCache.clear()
You can access a cache for a domain classes using its full class name, e.g.
def cache = sessionFactory.getSecondLevelCacheRegion('com.foo.bar.Book')
and clear it via
sessionFactory.getSecondLevelCacheRegion('com.foo.bar.Book').clear()
You can also call evict() on the sessionFactory for an entire class
sessionFactory.evict(com.foo.bar.Book)
or for an individual instance
sessionFactory.evict(com.foo.bar.Book, 42)

Resources