Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

App engine datastore - query on Enum fields

I am using GAE(Java) with JDO for persistence.

I have an entity with a Enum field which is marked as @Persistent and gets saved correctly into the datastore (As observed from the Datastore viewer in Development Console). But when I query these entities putting a filter based on the Enum value, it is always returning me all the entities whatever value I specify for the enum field.

I know GAE java supports enums being persisted just like basic datatypes. But does it also allow retrieving/querying based on them? Google search could not point me to any such example code.

Details:

I have printed the Query just before being executed. So in two cases the query looks like -

SELECT FROM com.xxx.yyy.User WHERE role == super ORDER BY key desc RANGE 0,50

SELECT FROM com.xxx.yyy.User WHERE role == admin ORDER BY key desc RANGE 0,50

Both above queries return me all the User entities from datastore in spite of datastore viewer showing some Users are of type 'admin' and some are of type 'super'.

like image 663
Gopi Avatar asked Feb 28 '10 03:02

Gopi


3 Answers

For time being, I have replaced the Enums with simple integer constants. Reported this case as an issue in the google app engine : http://code.google.com/p/googleappengine/issues/detail?id=2927

like image 172
Gopi Avatar answered Sep 28 '22 06:09

Gopi


For a parameter other than a String or an int, I believe you need to use declareParameters instead. Try something like this:

Query q = pm.newQuery(com.xxx.yyy.User.class);
q.setFilter("role == p1");  //p1 is a variable place holder
q.declareParameters("Enum p1"); //here you define the data type for the variable, in this case an Enum
q.setRange(0, 50);
q.setOrdering("key desc");

AbstractQueryResult results = (AbstractQueryResult) pm.newQuery(q).execute(admin);

or if you want more gql like syntax -

Query query = pm.newQuery("SELECT FROM com.xxx.yyy.User WHERE role == p1 ORDER BY key desc RANGE 0,50");
query.declareParameters("Enum p1");
AbstractQueryResult results = (AbstractQueryResult) pm.newQuery(q).execute(admin);
like image 41
dayal Avatar answered Sep 28 '22 06:09

dayal


You need to use your enum's class name when you declare the query parameter.

For example, if you build your query using the method style, and assuming your enum is called Role and is declared under the User class, you can do something like the following:

Query query = pm.newQuery(com.xxx.yyy.User.class);
query.setFilter("role == roleParam");
query.declareParameters(com.xxx.yyy.User.Role.class.getName() + " roleParam");
like image 36
Gerardo Figueroa Avatar answered Sep 28 '22 06:09

Gerardo Figueroa