autofetch builds different queryHashCodes between successive runs of your application. 1) avaje builds hash-codes using xyz.class.hashCode() which does NOT results into the same hashCode() between application starts. It seems the hashCode of a class is stable only within the same instance of a JVM. I propose to fix this using xyz.class.getName().hashCode() 2) In SimpleExpression there is an enum which behaves like a class, thush hashCode() can't be called there too. proposal: enum.name().hashCode() Here is a patch which solves that:
Index: ../ebean/src/com/avaje/ebean/expression/IdExpression.java =================================================================== --- ../ebean/src/com/avaje/ebean/expression/IdExpression.java (revision 141) +++ ../ebean/src/com/avaje/ebean/expression/IdExpression.java Sun Feb 22 11:37:22 CET 2009 @@ -42,7 +42,7 @@ public int queryPlanHash() { // this number is unique for a given bean type // which is all that is required - return IdExpression.class.hashCode(); + return IdExpression.class.getName().hashCode(); } public int queryBindHash() { Index: ../ebean/src/com/avaje/ebean/server/transaction/TableModInfo.java =================================================================== --- ../ebean/src/com/avaje/ebean/server/transaction/TableModInfo.java (revision 141) +++ ../ebean/src/com/avaje/ebean/server/transaction/TableModInfo.java Sun Feb 22 11:37:22 CET 2009 @@ -76,7 +76,7 @@ } public int hashCode() { - int hc = TableModInfo.class.hashCode(); + int hc = TableModInfo.class.getName().hashCode(); hc = hc*31 + tableName.hashCode(); return hc; } Index: ../ebean/src/com/avaje/ebean/expression/LogicExpression.java =================================================================== --- ../ebean/src/com/avaje/ebean/expression/LogicExpression.java (revision 141) +++ ../ebean/src/com/avaje/ebean/expression/LogicExpression.java Sun Feb 22 11:37:22 CET 2009 @@ -61,7 +61,7 @@ * Based on the joinType plus the two expressions. */ public int queryPlanHash() { - int hc = LogicExpression.class.hashCode() + joinType.hashCode(); + int hc = LogicExpression.class.getName().hashCode() + joinType.hashCode(); hc = hc * 31 + expOne.queryPlanHash(); hc = hc * 31 + expTwo.queryPlanHash(); return hc; Index: ../ebean/src/com/avaje/ebean/util/DefaultExpressionList.java =================================================================== --- ../ebean/src/com/avaje/ebean/util/DefaultExpressionList.java (revision 141) +++ ../ebean/src/com/avaje/ebean/util/DefaultExpressionList.java Sun Feb 22 11:37:22 CET 2009 @@ -1,11 +1,5 @@ package com.avaje.ebean.util; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; - import com.avaje.ebean.Query; import com.avaje.ebean.QueryListener; import com.avaje.ebean.expression.Expr; @@ -15,6 +9,12 @@ import com.avaje.ebean.expression.InternalExpressionList; import com.avaje.ebean.expression.Junction; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + /** * Default implementation of ExpressionList. */ @@ -125,7 +125,7 @@ * Calculate a hash based on the expressions but excluding the actual bind values. */ public int queryPlanHash() { - int hash = DefaultExpressionList.class.hashCode(); + int hash = DefaultExpressionList.class.getName().hashCode(); for (int i = 0, size=list.size(); i < size; i++) { Expression expression = list.get(i); hash = hash*31 + expression.queryPlanHash(); @@ -137,7 +137,7 @@ * Calculate a hash based on the expressions. */ public int queryBindHash() { - int hash = DefaultExpressionList.class.hashCode(); + int hash = DefaultExpressionList.class.getName().hashCode(); for (int i = 0, size=list.size(); i < size; i++) { Expression expression = list.get(i); hash = hash*31 + expression.queryBindHash(); Index: ../ebean/src/com/avaje/ebean/server/net/Endpoint.java =================================================================== --- ../ebean/src/com/avaje/ebean/server/net/Endpoint.java (revision 141) +++ ../ebean/src/com/avaje/ebean/server/net/Endpoint.java Sun Feb 22 11:37:22 CET 2009 @@ -81,7 +81,7 @@ } public int hashCode() { - int hc = Endpoint.class.hashCode(); + int hc = Endpoint.class.getName().hashCode(); hc = 31*hc + fullName.hashCode(); return hc; } Index: ../ebean/src/com/avaje/ebean/expression/AllEqualsExpression.java =================================================================== --- ../ebean/src/com/avaje/ebean/expression/AllEqualsExpression.java (revision 141) +++ ../ebean/src/com/avaje/ebean/expression/AllEqualsExpression.java Sun Feb 22 11:37:22 CET 2009 @@ -74,7 +74,7 @@ * */ public int queryPlanHash() { - int hc = AllEqualsExpression.class.hashCode(); + int hc = AllEqualsExpression.class.getName().hashCode(); Set> entries = propMap.entrySet(); Iterator> it = entries.iterator(); Index: ../ebean/src/com/avaje/ebean/query/DefaultOrmQuery.java =================================================================== --- ../ebean/src/com/avaje/ebean/query/DefaultOrmQuery.java (revision 141) +++ ../ebean/src/com/avaje/ebean/query/DefaultOrmQuery.java Sun Feb 22 11:38:27 CET 2009 @@ -1,12 +1,5 @@ package com.avaje.ebean.query; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.persistence.PersistenceException; - import com.avaje.ebean.EbeanServer; import com.avaje.ebean.Query; import com.avaje.ebean.QueryListener; @@ -25,6 +18,12 @@ import com.avaje.ebean.util.BindParams; import com.avaje.ebean.util.DefaultExpressionList; +import javax.persistence.PersistenceException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + /** * Default implementation of an Object Relational query. */ @@ -317,7 +316,7 @@ } public int hashCode() { - int hc = Query.class.hashCode(); + int hc = Query.class.getName().hashCode(); hc = hc * 31 + getQueryHash(); return hc; } Index: ../ebean/src/com/avaje/ebean/expression/NotExpression.java =================================================================== --- ../ebean/src/com/avaje/ebean/expression/NotExpression.java (revision 141) +++ ../ebean/src/com/avaje/ebean/expression/NotExpression.java Sun Feb 22 11:37:22 CET 2009 @@ -31,7 +31,7 @@ * Based on the expression. */ public int queryPlanHash() { - int hc = NotExpression.class.hashCode(); + int hc = NotExpression.class.getName().hashCode(); hc = hc * 31 + exp.queryPlanHash(); return hc; } Index: ../ebean/src/com/avaje/ebean/expression/CaseInsensitiveEqualExpression.java =================================================================== --- ../ebean/src/com/avaje/ebean/expression/CaseInsensitiveEqualExpression.java (revision 141) +++ ../ebean/src/com/avaje/ebean/expression/CaseInsensitiveEqualExpression.java Sun Feb 22 11:37:22 CET 2009 @@ -31,7 +31,7 @@ * Based on the propertyName. */ public int queryPlanHash() { - int hc = CaseInsensitiveEqualExpression.class.hashCode(); + int hc = CaseInsensitiveEqualExpression.class.getName().hashCode(); hc = hc * 31 + propertyName.hashCode(); return hc; } Index: ../ebean/src/com/avaje/ebean/expression/LikeExpression.java =================================================================== --- ../ebean/src/com/avaje/ebean/expression/LikeExpression.java (revision 141) +++ ../ebean/src/com/avaje/ebean/expression/LikeExpression.java Sun Feb 22 11:37:22 CET 2009 @@ -44,7 +44,7 @@ * Based on caseInsensitive and the property name. */ public int queryPlanHash() { - int hc = LikeExpression.class.hashCode(); + int hc = LikeExpression.class.getName().hashCode(); hc = hc * 31 + (caseInsensitive ? 0 : 1); hc = hc * 31 + propertyName.hashCode(); return hc; Index: ../ebean/src/com/avaje/ebean/expression/NullExpression.java =================================================================== --- ../ebean/src/com/avaje/ebean/expression/NullExpression.java (revision 141) +++ ../ebean/src/com/avaje/ebean/expression/NullExpression.java Sun Feb 22 11:37:22 CET 2009 @@ -39,7 +39,7 @@ * Based on notNull flag and the propertyName. */ public int queryPlanHash() { - int hc = NullExpression.class.hashCode(); + int hc = NullExpression.class.getName().hashCode(); hc = hc * 31 + (notNull ? 1 : 0); hc = hc * 31 + propertyName.hashCode(); return hc; Index: ../ebean/src/com/avaje/ebean/expression/SimpleExpression.java =================================================================== --- ../ebean/src/com/avaje/ebean/expression/SimpleExpression.java (revision 141) +++ ../ebean/src/com/avaje/ebean/expression/SimpleExpression.java Sun Feb 22 11:37:22 CET 2009 @@ -66,9 +66,9 @@ * Based on the type and propertyName. */ public int queryPlanHash() { - int hc = SimpleExpression.class.hashCode(); + int hc = SimpleExpression.class.getName().hashCode(); hc = hc * 31 + propertyName.hashCode(); - hc = hc * 31 + type.hashCode(); + hc = hc * 31 + type.name().hashCode(); return hc; } Index: ../ebean/src/com/avaje/ebean/expression/RawExpression.java =================================================================== --- ../ebean/src/com/avaje/ebean/expression/RawExpression.java (revision 141) +++ ../ebean/src/com/avaje/ebean/expression/RawExpression.java Sun Feb 22 11:37:22 CET 2009 @@ -34,7 +34,7 @@ * Based on the sql. */ public int queryPlanHash() { - int hc = RawExpression.class.hashCode(); + int hc = RawExpression.class.getName().hashCode(); hc = hc * 31 + sql.hashCode(); return hc; } Index: ../ebean/src/com/avaje/ebean/expression/BetweenExpression.java =================================================================== --- ../ebean/src/com/avaje/ebean/expression/BetweenExpression.java (revision 141) +++ ../ebean/src/com/avaje/ebean/expression/BetweenExpression.java Sun Feb 22 11:37:22 CET 2009 @@ -37,7 +37,7 @@ * Based on the property name. */ public int queryPlanHash() { - int hc = BetweenExpression.class.hashCode(); + int hc = BetweenExpression.class.getName().hashCode(); hc = hc * 31 + propertyName.hashCode(); return hc; } Index: ../ebean/src/com/avaje/ebean/expression/InExpression.java =================================================================== --- ../ebean/src/com/avaje/ebean/expression/InExpression.java (revision 141) +++ ../ebean/src/com/avaje/ebean/expression/InExpression.java Sun Feb 22 11:37:22 CET 2009 @@ -45,7 +45,7 @@ * Based on the number of values in the in clause. */ public int queryPlanHash() { - return InExpression.class.hashCode() + 31 * values.length; + return InExpression.class.getName().hashCode() + 31 * values.length; } public int queryBindHash() { Index: ../ebean/src/com/avaje/ebean/expression/JunctionExpression.java =================================================================== --- ../ebean/src/com/avaje/ebean/expression/JunctionExpression.java (revision 141) +++ ../ebean/src/com/avaje/ebean/expression/JunctionExpression.java Sun Feb 22 11:37:22 CET 2009 @@ -72,7 +72,7 @@ * Based on Junction type and all the expression contained. */ public int queryPlanHash() { - int hc = JunctionExpression.class.hashCode(); + int hc = JunctionExpression.class.getName().hashCode(); for (int i = 0; i < list.size(); i++) { hc = hc * 31 + joinType.hashCode(); hc = hc * 31 + list.get(i).queryPlanHash(); @@ -82,7 +82,7 @@ } public int queryBindHash() { - int hc = JunctionExpression.class.hashCode(); + int hc = JunctionExpression.class.getName().hashCode(); for (int i = 0; i < list.size(); i++) { hc = hc * 31 + list.get(i).queryBindHash(); } |