JPA Query with IN clause - google-app-engine

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

Related

is it possible to use GQL from a java appengine application?

Is it possible to use GQL from a java appengine application?
I've seen several references to GqlQuery object in various packages here and there, but I see nothing about how to use it from an AppEngine application.
Is it possible? What maven package should I use for it? If it's available, is it stable -or- pre-release?
Thanks, Chad
I think it is possible. I did some googling and I have noted here what I found.
Disclaimer: I have tested none of this and I, like Andrei, would strongly recommend using Objectify.
You can get a datastore instance from the API. From https://cloud.google.com/datastore/docs/datastore-api-tutorial:
// Create an authorized Datastore service using Application Default Credentials.
private final Datastore datastore = DatastoreOptions.defaultInstance().service();
You would need at least the following Maven package. Like it says it is in Beta.
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-datastore-protobuf</artifactId>
<version>v1beta2-rev1-4.0.0</version>
</dependency>
You could then do a GQL query like this.
From https://cloud.google.com/datastore/docs/concepts/gql:
// import static com.google.api.services.datastore.client.DatastoreHelper.*;
GqlQuery.Builder query = GqlQuery.newBuilder().setQueryString("SELECT * FROM Person");
RunQueryRequest request = RunQueryRequest.newBuilder().setGqlQuery(query).build();
RunQueryResponse response = datastore.runQuery(request);
List<Entity> results = new ArrayList<Entity>();
for (EntityResult entityResult : response.getBatch().getEntityResultList()) {
results.add(entityResult.getEntity());
}

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

Google Task Queues JSON API Transactions

Is it possible to put a record to Google Cloud Datastore and a task to the TaskQueue atomically outside of App Engine using their REST APIs?
Basically achieve this (below) but in Container Engine and without using the high-level App Engine-specific APIs.
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
Queue queue = QueueFactory.getDefaultQueue();
try {
Transaction txn = ds.beginTransaction();
// ...
queue.add(TaskOptions.Builder.withUrl("/path/to/my/worker"));
// ...
txn.commit();
} catch (DatastoreFailureException e) {
}
This is not currently possible using the Cloud Datastore API.

Load data from Google Cloud Storage to BigQuery using Java

I want to upload data from Google Cloud Storage to BigQuery, but I can't find any Java sample code describing how to do this. Would someone please give me some hint as how to do this?
What I actually wanna do is to transfer data from Google App Engine tables to BigQuery (and sync on a daily basis), so that I can do some analysis. I use the Google Cloud Storage Service in Google App Engine to write (new) records to files in Google Cloud Storage, and the only missing part is to append the data to tables in BigQuery (or create a new table for first time write). Admittedly I can manually upload/append the data using the BigQuery browser tool, but I would like it to be automatic, otherwise I need to manually do it everyday.
I don't know of any java samples for loading tables from Google Cloud Storage into BigQuery. That said, if you follow the instructions for running query jobs here, you can run a Load job instead with the folowing:
Job job = new Job();
JobConfiguration config = new JobConfiguration();
JobConfigurationLoad loadConfig = new JobConfigurationLoad();
config.setLoad(loadConfig);
job.setConfiguration(config);
// Set where you are importing from (i.e. the Google Cloud Storage paths).
List<String> sources = new ArrayList<String>();
sources.add("gs://bucket/csv_to_load.csv");
loadConfig.setSourceUris(sources);
// Describe the resulting table you are importing to:
TableReference tableRef = new TableReference();
tableRef.setDatasetId("myDataset");
tableRef.setTableId("myTable");
tableRef.setProjectId(projectId);
loadConfig.setDestinationTable(tableRef);
List<TableFieldSchema> fields = new ArrayList<TableFieldSchema>();
TableFieldSchema fieldFoo = new TableFieldSchema();
fieldFoo.setName("foo");
fieldFoo.setType("string");
TableFieldSchema fieldBar = new TableFieldSchema();
fieldBar.setName("bar");
fieldBar.setType("integer");
fields.add(fieldFoo);
fields.add(fieldBar);
TableSchema schema = new TableSchema();
schema.setFields(fields);
loadConfig.setSchema(schema);
// Also set custom delimiter or header rows to skip here....
// [not shown].
Insert insert = bigquery.jobs().insert(projectId, job);
insert.setProjectId(projectId);
JobReference jobRef = insert.execute().getJobReference();
// ... see rest of codelab for waiting for job to complete.
For more information on the load configuration object, see the javadoc here.

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

Resources