Thursday, January 02, 2014

Why was I getting a "java.lang.IllegalArgumentException: Type mismatch" when trying a projection query on GAE

I was about to ask the following Q on StackOverflow.com but ended up finding the answer myself before even posting so I decided to make this into a new blog post.

I have two code snippets which I am trying to run on the development server of Google App Engine SDK v1.8.8 for Java.

The first:

    return datastore.get(KeyFactory.createKey(Kinds.Provider,provider_id));
    
works as expected and returns the Provider Entity from the Data Store.

But when I tried to change it to a projection Query so that it will return only some of the fields like this: 

    Filter filter=new FilterPredicate(Entity.KEY_RESERVED_PROPERTY,
                                      Query.FilterOperator.EQUAL,
                                      KeyFactory.createKey(Kinds.Provider,provider_id));
    Query q = new Query(Kinds.Provider)
                .setFilter(filter)
.addProjection(new PropertyProjection("address", String.class))
       .addProjection(new PropertyProjection("last_modified", String.class));;
}
    PreparedQuery pq = datastore.prepare(q);
    log.info("query:" + q.toString());
    
    Entity result = pq.asSingleEntity();

I am getting a the following Exception:


    java.lang.IllegalArgumentException: Type mismatch.
    at com.google.appengine.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:96)
    at com.google.appengine.api.datastore.RawValue.asType(RawValue.java:61)
    at com.google.appengine.api.datastore.PropertyProjection.getValue(PropertyProjection.java:65)
    at com.google.appengine.api.datastore.EntityTranslator.createFromPb(EntityTranslator.java:29)
    at com.google.appengine.api.datastore.QueryResultsSourceImpl.processQueryResult(QueryResultsSourceImpl.java:199)
    at com.google.appengine.api.datastore.QueryResultsSourceImpl.loadMoreEntities(QueryResultsSourceImpl.java:106)
    at com.google.appengine.api.datastore.QueryResultIteratorImpl.ensureLoaded(QueryResultIteratorImpl.java:155)
    at com.google.appengine.api.datastore.QueryResultIteratorImpl.nextList(QueryResultIteratorImpl.java:110)
    at com.google.appengine.api.datastore.LazyList.forceResolveToIndex(LazyList.java:93)
    at com.google.appengine.api.datastore.LazyList.resolveToIndex(LazyList.java:73)
    at com.google.appengine.api.datastore.LazyList.resolveToIndex(LazyList.java:56)
    at com.google.appengine.api.datastore.LazyList.isEmpty(LazyList.java:260)
    at com.google.appengine.api.datastore.PreparedQueryImpl.asSingleEntity(PreparedQueryImpl.java:74)

as I was copying This exception For my StackOverflow.com Q I discovered that there was another exception before that

12:09:18 PM com.google.appengine.api.datastore.dev.LocalCompositeIndexManager updateIndexFile
SEVERE: Unable to write some_path\war\WEB-INF\datastore-indexes.xml
java.io.FileNotFoundException: some_path\war\WEB-INF\appengine-generated\datastore-indexes-auto.xml (Access is denied)

Now it makes more sense...
Projection Queries require indexes to be created as explained here If the datastore-indexes-auto.xml is read only... well you now know what happens then...

well...
I thought this was the end of it but no... After making the file writeable, GAE indeed added an index to it but I still get the original 
IllegalArgumentException 

logging the querys .toString() yeilded:

SELECT last_modified, address FROM Provider WHERE __key__ = Provider(99)


Finally It turned out the error was absolutely justified...
In:

.addProjection(new PropertyProjection("last_modified", String.class));;

Last Modified was a Long and not a String...

1 comment:

Unknown said...

The most possible cause of this error can be lack of proper activation of the windows this can usually happen if this copy of windows is not genuine

 
Clicky Web Analytics