Update query using JPA and Google App Engine - 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

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.

JPA Query to get entity type

I am trying to write a JPA query to get the type for a particular entity, given the id of the entity. I have an abstract class Account, and concrete subclasses CustomerAccount and AdministratorAccount. The id is an attribute of the Account, so I am trying to construct a query to return the Type (i.e. foo.bar.CustomerAccount) given the ID of the account.
I tried the following:
String sql = "SELECT TYPE(a) from Account a where a.id = :userId";
But that doesn't seem to work. Any ideas? I'm using the google app engine jpa implementation (datanucleus) if that helps.
Firstly, FWIW you are using Google's JPA plugin which just happens to use some ancient jars provided by the DataNucleus project. You are not using DataNucleus JPA.
Secondly, the datastore "GAE/Datastore" and Google's JPA plugin are not likely to support JPQL "TYPE" since that came along after their plugin was developed.
Finally, you maybe would get the info you want in a more efficient way by just doing
Object obj = em.find(Account.class, id);
Class type = obj.getClass();
since this also inspects the L1/L2 caches

JPA Query with IN clause

I am using the Google App Engine and JPA. I tried to execute the following query
List<String> countryList = new ArrayList<String>();
countryList.add("DE");
countryList.add("EN");
Query q = em.createQuery("select t from FOO t where t.country IN :country ");
q.setParameter("country", countryList);
I receive the Exception that Google App Engine Datastore does not support the IN Opperator. Does anyone know a suitable alternative?
Regards
Michael

Entity not queried immediately after commit in data nucleus JPA

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);

HTML5 database storage (SQL lite) - few questions

Hy there,
I can't find enough beginner resources on the web about HTML5 database storage usage examples (CRUD)
I'm opening(creating) my DB like this:
var db;
$(document).ready(function()
{
try
{
if (!window.openDatabase) {
alert('Not Supported -> Please try with a WebKit Browser');
} else {
var shortName = 'mydatab';
var version = '1.0';
var displayName = 'User Settings Database';
var maxSize = 3072*1024; // = 3MB in bytes 65536
db = openDatabase(shortName, version, displayName, maxSize);
}
}
catch(e)
{
if (e == 2) {
alert("Invalid database version.");
} else {
alert("Unknown error "+e+".");
}return;
}
});
QUESTION 1: How many databases can i create and use on one domain?
QUESTION 2. How to delete (drop) a database. -> i have not figured this out yet.
To create sql queries you use transaction:
function nullDataHandler(transaction, results) { }
function createTables(db)
{
db.transaction(function (transaction)
{
//first query causes the transaction to (intentionally) fail if the table exists.
transaction.executeSql('CREATE TABLE people(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL DEFAULT "John Doe", shirt TEXT NOT NULL DEFAULT "Purple");', [], nullDataHandler, errorHandler);
});
}
QUESTION 3: How so is the above transaciton failed if a table exists? Is the nullDataHandler involved to do this? Where on the web is there documentation explaining the executeSql API? Arguments?
thx
The spec you're looking for is Web SQL Database. A quick reading suggests:
There is no limit, although once your databases increase beyond a certain size (5MB seems to be the default), the browser will prompt the user to allow for more space.
There is no way, in the current spec, to delete databases.
The executeSql() function takes an optional error callback argument.
HTML5 Doctor also has a good introduction.
Going forward, though, I'd recommend looking at Indexed DB. Web SQL has essentially been abandoned since there is no standard for SQL / SQLite. Even Microsoft has endorsed Indexed DB. See Consensus emerges for key Web app standard.
CREATE TABLE IF NOT EXISTS table_name
will create a table table_name only if if does not exist.
I found the following WebSQL tutorials helpful for basic CRUD operations, as they contained examples, and explained what the code was doing:
A Simple TODO list using HTML5 WebDatabases
HTML5 Web SQL Database
And the following links for SequelSphere (an HTML5 JavaScript SQL Relational Database Alternative to WebSQL that works in all browsers, storing data in LocalStorage and IndexedDB):
SequelSphere basic Usage instructions
API Documentation
Full Index of Guides and Helper Documentation
Using PersistenceJS there is a persistence.reset API which will wipe the database clean.
PersistenceJS Site
For developing / testing purposes, you can view content and delete webSQL, IndexedDB, cookies, etc by searching for your domain name at this URL in Chrome:
chrome://settings/cookies
There, you can delete all the storage for a domain or just certain local storage entities. Yes, the URL implies just 'cookies', but the interface at this URL includes all types of offline storage.
It would be great I think if the Chrome developer tools interface had the ability to right-click and delete a data storage entity in the Resources tab along with inspecting the content. But for now, all I know of is the settings/cookies URL.
It is supported on iOS safari,chrome and some latest version of opera....it's not yet adopted by IE and Firefox that's it......what more one can ask than local db on browser which has relational db system...so u can query it easily and handle complex data....which is very tougher in key vale based systems..
I remember reading it even supports upto one gb.i am not sure....
Note:
1)I'd like to mention one point there is a IDE called Dashcode which let's u build web apps that looks like iOS native.even there also web SQL is used.
2)actually web SQL is a implementation of SQLite on browsers.
3)SQLite is most prefered in both iOS and android as db for native code..
The drawbacks of SQLite:
The Lack of concurrency support but which is not a problem in browser as it's gonna be used by single user at a time..this is a case also in mobile.
Conclusions:
Web Sql is abandoned by w3 that's a sad thing so we've to explore other options.

Resources