qickrooms / objectify-appengine

Automatically exported from code.google.com/p/objectify-appengine
MIT License
0 stars 0 forks source link

Objectify automatically uses hybrid queries when it cannot #234

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I'm using Objectify v5.1.5 and am attempting to run a query that uses an "in" 
query along with an orderBy clause.

SELECT * FROM MyEntity WHERE someProperty IN ( 'value1', 'value2') ORDER BY 
some.other.property DESC

This produces the following error on my system:

"The provided keys-only multi-query needs to perform some sorting in memory.  
As a result, this query can only be sorted by the key property as this is the 
only property that is available in memory."

Which would make since if I was using a keys only query. However I am not 
attempting to use a keys only query. After some digging around and enabling the 
"FINEST" logging, I found the following:

FINEST com.googlecode.objectify.impl.QueryEngine queryHybrid: Starting hybrid 
query

Objectify is enabling a hybrid query which automatically converts the query to 
a keys only query, thus the error. 

We just recently converted from objectify 4 to 5 and that conversion is what 
caused this error. I noticed that Objectify 4 and 5 handles the logic to use a 
hybrid query differently.

The following is how objectify 4 decides this should be a hybrid query. Notice 
the "hasMulti && hasNonKeyOrder" makes the query non-hybrid.

https://code.google.com/p/objectify-appengine/source/browse/src/main/java/com/go
oglecode/objectify/impl/QueryImpl.java?name=v4

/** Produces the basic iterable on results based on the current query.  Used to 
generate other iterables via transformation. */
        private QueryResultIterable<T> resultIterable() {
                boolean hybridize = hybrid;

                if (!hasExplicitHybrid) {
                        // These are the special conditions we know about.  It may expand.

                        if (hasMulti && hasNonKeyOrder)
                                hybridize = false;
                }

                if (hybridize)
                        return loader.createQueryEngine().queryHybrid(this.getActualQuery(), this.fetchOptions());
                else
                        return loader.createQueryEngine().queryNormal(this.getActualQuery(), this.fetchOptions());
        }

The following is how objectify 5 decides if the query should be a hybrid query. 
This is basically saying that if caching is enabled, do a hybrid query. No 
check for multi queries with sort orders by a property.

https://code.google.com/p/objectify-appengine/source/browse/src/main/java/com/go
oglecode/objectify/impl/QueryImpl.java?name=master

/** Produces the basic iterable on results based on the current query.  Used to 
generate other iterables via transformation. */
        private QueryResultIterable<T> resultIterable() {
                if (!actual.getProjections().isEmpty())
                        return loader.createQueryEngine().queryProjection(this.getActualQuery(), this.fetchOptions());
                else if (shouldHybridize())
                        return loader.createQueryEngine().queryHybrid(this.getActualQuery(), this.fetchOptions());
                else
                        return loader.createQueryEngine().queryNormal(this.getActualQuery(), this.fetchOptions());
        }

 /**
         * @return true if we should hybridize this query
         */
        private boolean shouldHybridize() {
                if (hybrid != null)
                        return hybrid;

                // If the class is cacheable
                if (classRestriction != null && loader.getObjectifyImpl().getCache() && fact().getMetadata(classRestriction).getCacheExpirySeconds() != null)
                        return true;

                return false;
        }

Objectify should recognize when a hybrid query is not appropriate and use a 
normal query instead.

Original issue reported on code.google.com by brian.ch...@aawhere.com on 3 Apr 2015 at 4:56

GoogleCodeExporter commented 9 years ago

Original comment by lhori...@gmail.com on 3 Apr 2015 at 5:09