mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-11-12 22:41:35 +00:00
Merge branch 'md5-for-querybindhash' of https://github.com/FOCONIS/ebean into FOCONIS-md5-for-querybindhash
This commit is contained in:
commit
cd6df2be39
40 files changed
+436
-137
No files matched your search
@@ -0,0 +1,37 @@
|
|||||||
|
package io.ebeaninternal.api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BindHash implementation.
|
||||||
|
*
|
||||||
|
* @author Roland Praml, FOCONIS AG
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface BindHash {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update with boolean value.
|
||||||
|
*/
|
||||||
|
BindHash update(boolean boolValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update with int value.
|
||||||
|
*/
|
||||||
|
BindHash update(int intValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update with long value.
|
||||||
|
*/
|
||||||
|
BindHash update(long longValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update with object value.
|
||||||
|
*/
|
||||||
|
BindHash update(Object value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* finishes the hash. May be used to compute internal state. After finish, no
|
||||||
|
* update method must be called
|
||||||
|
*/
|
||||||
|
void finish();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -54,12 +54,11 @@ public class BindParams implements Serializable {
|
|||||||
positionedParameters.clear();
|
positionedParameters.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
int hc = namedParameters.hashCode();
|
hash.update(positionedParameters.size());
|
||||||
for (Param positionedParameter : positionedParameters) {
|
for (Param positionedParameter : positionedParameters) {
|
||||||
hc = hc * 92821 + positionedParameter.hashCode();
|
positionedParameter.queryBindHash(hash);
|
||||||
}
|
}
|
||||||
return hc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -422,6 +421,10 @@ public class BindParams implements Serializable {
|
|||||||
return hc;
|
return hc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void queryBindHash(BindHash hash) {
|
||||||
|
hash.update(isInParam).update(isOutParam).update(type).update(inValue);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
return o != null && (o == this || (o instanceof Param) && hashCode() == o.hashCode());
|
return o != null && (o == this || (o instanceof Param) && hashCode() == o.hashCode());
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ public class HashQuery {
|
|||||||
|
|
||||||
private final CQueryPlanKey planHash;
|
private final CQueryPlanKey planHash;
|
||||||
|
|
||||||
private final int bindHash;
|
private final BindHash bindHash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the HashQuery.
|
* Create the HashQuery.
|
||||||
*/
|
*/
|
||||||
public HashQuery(CQueryPlanKey planHash, int bindHash) {
|
public HashQuery(CQueryPlanKey planHash, BindHash bindHash) {
|
||||||
this.planHash = planHash;
|
this.planHash = planHash;
|
||||||
this.bindHash = bindHash;
|
this.bindHash = bindHash;
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,7 @@ public class HashQuery {
|
|||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hc = 92821 * planHash.hashCode();
|
int hc = 92821 * planHash.hashCode();
|
||||||
hc = 92821 * hc + bindHash;
|
hc = 92821 * hc + bindHash.hashCode();
|
||||||
return hc;
|
return hc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +39,6 @@ public class HashQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HashQuery e = (HashQuery) obj;
|
HashQuery e = (HashQuery) obj;
|
||||||
return e.bindHash == bindHash && e.planHash.equals(planHash);
|
return e.bindHash.equals(bindHash) && e.planHash.equals(planHash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ public interface SpiExpression extends Expression {
|
|||||||
/**
|
/**
|
||||||
* Return the hash value for the values that will be bound.
|
* Return the hash value for the values that will be bound.
|
||||||
*/
|
*/
|
||||||
int queryBindHash();
|
void queryBindHash(BindHash hash);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the expression is the same with respect to bind values.
|
* Return true if the expression is the same with respect to bind values.
|
||||||
|
|||||||
@@ -635,7 +635,7 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
|||||||
* query).
|
* query).
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
int queryBindHash();
|
void queryBindHash(BindHash hash);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies queries that are exactly the same including bind variables.
|
* Identifies queries that are exactly the same including bind variables.
|
||||||
|
|||||||
+4
-3
@@ -1,5 +1,6 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
|
|
||||||
@@ -37,9 +38,9 @@ public abstract class AbstractTextExpression extends AbstractExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
return 0;
|
// do nothing, only execute against document store
|
||||||
}
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSameByBind(SpiExpression other) {
|
public boolean isSameByBind(SpiExpression other) {
|
||||||
|
|||||||
+4
-4
@@ -1,5 +1,6 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.ManyWhereJoins;
|
import io.ebeaninternal.api.ManyWhereJoins;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
@@ -122,14 +123,13 @@ class AllEqualsExpression extends NonPrepareExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
|
|
||||||
int hc = 92821;
|
hash.update(propMap.size());
|
||||||
for (Object value : propMap.values()) {
|
for (Object value : propMap.values()) {
|
||||||
hc = hc * 92821 + (value == null ? 0 : value.hashCode());
|
hash.update(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+5
-5
@@ -1,5 +1,6 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
|
|
||||||
@@ -49,12 +50,11 @@ public class ArrayContainsExpression extends AbstractExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
int hc = values[0].hashCode();
|
hash.update(values.length);
|
||||||
for (int i = 1; i < values.length; i++) {
|
for (int i = 0; i < values.length; i++) {
|
||||||
hc = hc * 92821 + values[i].hashCode();
|
hash.update(values[i]);
|
||||||
}
|
}
|
||||||
return hc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+3
-2
@@ -1,5 +1,6 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
|
|
||||||
@@ -33,8 +34,8 @@ public class ArrayIsEmptyExpression extends AbstractExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
return empty ? 0 : 92821;
|
hash.update(empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
|
|
||||||
@@ -49,10 +50,8 @@ class BetweenExpression extends AbstractExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
int hc = low().hashCode();
|
hash.update(low()).update(high());
|
||||||
hc = hc * 92821 + high().hashCode();
|
|
||||||
return hc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+3
-2
@@ -1,6 +1,7 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
import io.ebean.util.SplitName;
|
import io.ebean.util.SplitName;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.ManyWhereJoins;
|
import io.ebeaninternal.api.ManyWhereJoins;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
@@ -95,8 +96,8 @@ class BetweenPropertyExpression extends NonPrepareExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
return val().hashCode();
|
hash.update(val());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
|
|
||||||
@@ -39,8 +40,8 @@ class BitwiseExpression extends AbstractExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
return Long.hashCode(flags);
|
hash.update(flags).update(match);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+3
-2
@@ -1,5 +1,6 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
import io.ebeaninternal.server.el.ElPropertyValue;
|
import io.ebeaninternal.server.el.ElPropertyValue;
|
||||||
@@ -69,8 +70,8 @@ class CaseInsensitiveEqualExpression extends AbstractValueExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
return val().hashCode();
|
hash.update(val());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+4
-4
@@ -5,6 +5,7 @@ import io.ebean.LikeType;
|
|||||||
import io.ebean.bean.EntityBean;
|
import io.ebean.bean.EntityBean;
|
||||||
import io.ebean.event.BeanQueryRequest;
|
import io.ebean.event.BeanQueryRequest;
|
||||||
import io.ebean.util.SplitName;
|
import io.ebean.util.SplitName;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.ManyWhereJoins;
|
import io.ebeaninternal.api.ManyWhereJoins;
|
||||||
import io.ebeaninternal.api.NaturalKeyQueryData;
|
import io.ebeaninternal.api.NaturalKeyQueryData;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
@@ -241,12 +242,11 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio
|
|||||||
* Return a hash for the actual bind values used.
|
* Return a hash for the actual bind values used.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
int hc = DefaultExampleExpression.class.getName().hashCode();
|
hash.update(list.size());
|
||||||
for (SpiExpression aList : list) {
|
for (SpiExpression aList : list) {
|
||||||
hc = hc * 92821 + aList.queryBindHash();
|
aList.queryBindHash(hash);
|
||||||
}
|
}
|
||||||
return hc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+4
-4
@@ -26,6 +26,7 @@ import io.ebean.search.MultiMatch;
|
|||||||
import io.ebean.search.TextCommonTerms;
|
import io.ebean.search.TextCommonTerms;
|
||||||
import io.ebean.search.TextQueryString;
|
import io.ebean.search.TextQueryString;
|
||||||
import io.ebean.search.TextSimple;
|
import io.ebean.search.TextSimple;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.ManyWhereJoins;
|
import io.ebeaninternal.api.ManyWhereJoins;
|
||||||
import io.ebeaninternal.api.NaturalKeyQueryData;
|
import io.ebeaninternal.api.NaturalKeyQueryData;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
@@ -678,12 +679,11 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
|||||||
* Calculate a hash based on the expressions.
|
* Calculate a hash based on the expressions.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
int hash = DefaultExpressionList.class.getName().hashCode();
|
hash.update(list.size());
|
||||||
for (SpiExpression aList : list) {
|
for (SpiExpression aList : list) {
|
||||||
hash = hash * 92821 + aList.queryBindHash();
|
aList.queryBindHash(hash);
|
||||||
}
|
}
|
||||||
return hash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+3
-2
@@ -1,6 +1,7 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
import io.ebean.event.BeanQueryRequest;
|
import io.ebean.event.BeanQueryRequest;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.ManyWhereJoins;
|
import io.ebeaninternal.api.ManyWhereJoins;
|
||||||
import io.ebeaninternal.api.NaturalKeyQueryData;
|
import io.ebeaninternal.api.NaturalKeyQueryData;
|
||||||
import io.ebeaninternal.api.SpiEbeanServer;
|
import io.ebeaninternal.api.SpiEbeanServer;
|
||||||
@@ -91,8 +92,8 @@ class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreExpress
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
return subQuery.queryBindHash();
|
subQuery.queryBindHash(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.ManyWhereJoins;
|
import io.ebeaninternal.api.ManyWhereJoins;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
@@ -77,8 +78,8 @@ class IdExpression extends NonPrepareExpression implements SpiExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
return value.hashCode();
|
hash.update(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
import io.ebean.event.BeanQueryRequest;
|
import io.ebean.event.BeanQueryRequest;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.ManyWhereJoins;
|
import io.ebeaninternal.api.ManyWhereJoins;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
@@ -133,8 +134,11 @@ public class IdInExpression extends NonPrepareExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
return idCollection.hashCode();
|
hash.update(idCollection.size());
|
||||||
|
for (Object elem : idCollection) {
|
||||||
|
hash.update(elem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.ebeaninternal.server.expression;
|
|||||||
|
|
||||||
import io.ebean.bean.EntityBean;
|
import io.ebean.bean.EntityBean;
|
||||||
import io.ebean.event.BeanQueryRequest;
|
import io.ebean.event.BeanQueryRequest;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.NaturalKeyQueryData;
|
import io.ebeaninternal.api.NaturalKeyQueryData;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
@@ -176,12 +177,11 @@ class InExpression extends AbstractExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
int hc = 92821;
|
hash.update(bindValues.size());
|
||||||
for (Object bindValue : bindValues) {
|
for (Object bindValue : bindValues) {
|
||||||
hc = 92821 * hc + bindValue.hashCode();
|
hash.update(bindValue);
|
||||||
}
|
}
|
||||||
return hc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package io.ebeaninternal.server.expression;
|
|||||||
import io.ebean.Pairs;
|
import io.ebean.Pairs;
|
||||||
import io.ebean.Pairs.Entry;
|
import io.ebean.Pairs.Entry;
|
||||||
import io.ebean.event.BeanQueryRequest;
|
import io.ebean.event.BeanQueryRequest;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.NaturalKeyQueryData;
|
import io.ebeaninternal.api.NaturalKeyQueryData;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
@@ -124,12 +125,11 @@ class InPairsExpression extends AbstractExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
int hc = 92821;
|
hash.update(entries.size());
|
||||||
for (Pairs.Entry entry : entries) {
|
for (Pairs.Entry entry : entries) {
|
||||||
hc = 92821 * hc + entry.hashCode();
|
hash.update(entry.getA()).update(entry.getB());
|
||||||
}
|
}
|
||||||
return hc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
import io.ebean.event.BeanQueryRequest;
|
import io.ebean.event.BeanQueryRequest;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.SpiEbeanServer;
|
import io.ebeaninternal.api.SpiEbeanServer;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
@@ -72,8 +73,8 @@ class InQueryExpression extends AbstractExpression implements UnsupportedDocStor
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
return subQuery.queryBindHash();
|
subQuery.queryBindHash(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
|
|
||||||
@@ -47,10 +48,8 @@ class InRangeExpression extends AbstractExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
int hc = low().hashCode();
|
hash.update(low()).update(high());
|
||||||
hc = hc * 92821 + high().hashCode();
|
|
||||||
return hc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.ManyWhereJoins;
|
import io.ebeaninternal.api.ManyWhereJoins;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
@@ -103,8 +104,8 @@ class IsEmptyExpression extends AbstractExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
return 1;
|
// no bind values
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
|
|
||||||
@@ -83,10 +84,8 @@ class JsonPathExpression extends AbstractExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
int hc = (value == null) ? 0 : value.hashCode();
|
hash.update(value).update(upperValue);
|
||||||
hc = (upperValue == null) ? hc : hc * 92821 + upperValue.hashCode();
|
|
||||||
return hc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import io.ebean.search.MultiMatch;
|
|||||||
import io.ebean.search.TextCommonTerms;
|
import io.ebean.search.TextCommonTerms;
|
||||||
import io.ebean.search.TextQueryString;
|
import io.ebean.search.TextQueryString;
|
||||||
import io.ebean.search.TextSimple;
|
import io.ebean.search.TextSimple;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.ManyWhereJoins;
|
import io.ebeaninternal.api.ManyWhereJoins;
|
||||||
import io.ebeaninternal.api.NaturalKeyQueryData;
|
import io.ebeaninternal.api.NaturalKeyQueryData;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
@@ -225,13 +226,12 @@ class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expression
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
int hc = JunctionExpression.class.getName().hashCode();
|
int hc = JunctionExpression.class.getName().hashCode();
|
||||||
List<SpiExpression> list = exprList.internalList();
|
List<SpiExpression> list = exprList.internalList();
|
||||||
for (SpiExpression aList : list) {
|
for (SpiExpression aList : list) {
|
||||||
hc = hc * 92821 + aList.queryBindHash();
|
aList.queryBindHash(hash);
|
||||||
}
|
}
|
||||||
return hc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
import io.ebean.LikeType;
|
import io.ebean.LikeType;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
import io.ebeaninternal.server.el.ElPropertyValue;
|
import io.ebeaninternal.server.el.ElPropertyValue;
|
||||||
@@ -70,8 +71,8 @@ class LikeExpression extends AbstractValueExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
return strValue().hashCode();
|
hash.update(strValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package io.ebeaninternal.server.expression;
|
|||||||
import io.ebean.Expression;
|
import io.ebean.Expression;
|
||||||
import io.ebean.Junction;
|
import io.ebean.Junction;
|
||||||
import io.ebean.event.BeanQueryRequest;
|
import io.ebean.event.BeanQueryRequest;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.ManyWhereJoins;
|
import io.ebeaninternal.api.ManyWhereJoins;
|
||||||
import io.ebeaninternal.api.NaturalKeyQueryData;
|
import io.ebeaninternal.api.NaturalKeyQueryData;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
@@ -168,10 +169,8 @@ abstract class LogicExpression implements SpiExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
int hc = expOne.queryBindHash();
|
hash.update(expOne).update(expTwo);
|
||||||
hc = hc * 92821 + expTwo.queryBindHash();
|
|
||||||
return hc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+3
-2
@@ -1,6 +1,7 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
import io.ebean.LikeType;
|
import io.ebean.LikeType;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
import io.ebeaninternal.server.el.ElPropertyValue;
|
import io.ebeaninternal.server.el.ElPropertyValue;
|
||||||
@@ -54,8 +55,8 @@ class NativeILikeExpression extends AbstractExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
return val.hashCode();
|
hash.update(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+3
-2
@@ -1,6 +1,7 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
import io.ebean.event.BeanQueryRequest;
|
import io.ebean.event.BeanQueryRequest;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.ManyWhereJoins;
|
import io.ebeaninternal.api.ManyWhereJoins;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
@@ -79,8 +80,8 @@ class NestedPathWrapperExpression implements SpiExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
return delegate.queryBindHash();
|
delegate.queryBindHash(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
import io.ebean.event.BeanQueryRequest;
|
import io.ebean.event.BeanQueryRequest;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.ManyWhereJoins;
|
import io.ebeaninternal.api.ManyWhereJoins;
|
||||||
import io.ebeaninternal.api.NaturalKeyQueryData;
|
import io.ebeaninternal.api.NaturalKeyQueryData;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
@@ -74,9 +75,8 @@ class NoopExpression implements SpiExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
// no bind values
|
// no bind values
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.ebeaninternal.server.expression;
|
|||||||
|
|
||||||
import io.ebean.Expression;
|
import io.ebean.Expression;
|
||||||
import io.ebean.event.BeanQueryRequest;
|
import io.ebean.event.BeanQueryRequest;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.ManyWhereJoins;
|
import io.ebeaninternal.api.ManyWhereJoins;
|
||||||
import io.ebeaninternal.api.NaturalKeyQueryData;
|
import io.ebeaninternal.api.NaturalKeyQueryData;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
@@ -99,8 +100,8 @@ final class NotExpression implements SpiExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
return exp.queryBindHash();
|
exp.queryBindHash(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
import io.ebean.util.SplitName;
|
import io.ebean.util.SplitName;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.ManyWhereJoins;
|
import io.ebeaninternal.api.ManyWhereJoins;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
@@ -94,7 +95,7 @@ class NullExpression extends AbstractExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
return (notNull ? 1 : 0);
|
hash.update(notNull);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.ebeaninternal.server.expression;
|
package io.ebeaninternal.server.expression;
|
||||||
|
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.ManyWhereJoins;
|
import io.ebeaninternal.api.ManyWhereJoins;
|
||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
@@ -73,12 +74,11 @@ class RawExpression extends NonPrepareExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
int hc = sql.hashCode();
|
hash.update(values.length);
|
||||||
for (Object value : values) {
|
for (Object value : values) {
|
||||||
hc = hc * 92821 + value.hashCode();
|
hash.update(value);
|
||||||
}
|
}
|
||||||
return hc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import io.ebean.plugin.ExpressionPath;
|
|||||||
import io.ebeaninternal.api.SpiExpression;
|
import io.ebeaninternal.api.SpiExpression;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
import io.ebeaninternal.server.el.ElPropertyValue;
|
import io.ebeaninternal.server.el.ElPropertyValue;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.NaturalKeyQueryData;
|
import io.ebeaninternal.api.NaturalKeyQueryData;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -121,8 +122,8 @@ public class SimpleExpression extends AbstractValueExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
return value().hashCode();
|
hash.update(value());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ import io.ebean.bean.PersistenceContext;
|
|||||||
import io.ebean.event.BeanQueryRequest;
|
import io.ebean.event.BeanQueryRequest;
|
||||||
import io.ebean.event.readaudit.ReadEvent;
|
import io.ebean.event.readaudit.ReadEvent;
|
||||||
import io.ebean.plugin.BeanType;
|
import io.ebean.plugin.BeanType;
|
||||||
|
import io.ebean.plugin.LoadErrorHandler;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.BindParams;
|
import io.ebeaninternal.api.BindParams;
|
||||||
import io.ebeaninternal.api.CQueryPlanKey;
|
import io.ebeaninternal.api.CQueryPlanKey;
|
||||||
import io.ebeaninternal.api.CacheIdLookup;
|
import io.ebeaninternal.api.CacheIdLookup;
|
||||||
@@ -283,6 +285,8 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
|||||||
|
|
||||||
private boolean orderById;
|
private boolean orderById;
|
||||||
|
|
||||||
|
private final String bindHashAlgorithm;
|
||||||
|
|
||||||
private ProfileLocation profileLocation;
|
private ProfileLocation profileLocation;
|
||||||
|
|
||||||
public DefaultOrmQuery(BeanDescriptor<T> desc, SpiEbeanServer server, ExpressionFactory expressionFactory) {
|
public DefaultOrmQuery(BeanDescriptor<T> desc, SpiEbeanServer server, ExpressionFactory expressionFactory) {
|
||||||
@@ -291,6 +295,7 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
|||||||
this.beanType = desc.getBeanType();
|
this.beanType = desc.getBeanType();
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.orderById = server.getServerConfig().isDefaultOrderById();
|
this.orderById = server.getServerConfig().isDefaultOrderById();
|
||||||
|
this.bindHashAlgorithm = "MD5"; // TODO: server.getServerConfig().isUseMd5BindHash();
|
||||||
this.disableLazyLoading = server.getServerConfig().isDisableLazyLoading();
|
this.disableLazyLoading = server.getServerConfig().isDisableLazyLoading();
|
||||||
this.expressionFactory = expressionFactory;
|
this.expressionFactory = expressionFactory;
|
||||||
this.detail = new OrmQueryDetail();
|
this.detail = new OrmQueryDetail();
|
||||||
@@ -1276,15 +1281,12 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
|||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int queryBindHash() {
|
public void queryBindHash(BindHash hash) {
|
||||||
int hc = (id == null ? 0 : id.hashCode());
|
hash.update(id);
|
||||||
hc = hc * 92821 + (whereExpressions == null ? 0 : whereExpressions.queryBindHash());
|
if (whereExpressions != null) whereExpressions.queryBindHash(hash);
|
||||||
hc = hc * 92821 + (havingExpressions == null ? 0 : havingExpressions.queryBindHash());
|
if (havingExpressions != null) havingExpressions.queryBindHash(hash);
|
||||||
hc = hc * 92821 + (bindParams == null ? 0 : bindParams.queryBindHash());
|
if (bindParams != null) bindParams.queryBindHash(hash);
|
||||||
hc = hc * 92821 + (asOf == null ? 0 : asOf.hashCode());
|
hash.update(asOf).update(versionsStart).update(versionsEnd);
|
||||||
hc = hc * 92821 + (versionsStart == null ? 0 : versionsStart.hashCode());
|
|
||||||
hc = hc * 92821 + (versionsEnd == null ? 0 : versionsEnd.hashCode());
|
|
||||||
return hc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1298,8 +1300,10 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
|||||||
public HashQuery queryHash() {
|
public HashQuery queryHash() {
|
||||||
// calculateQueryPlanHash is called just after potential AutoTune tuning
|
// calculateQueryPlanHash is called just after potential AutoTune tuning
|
||||||
// so queryPlanHash is calculated well before this method is called
|
// so queryPlanHash is calculated well before this method is called
|
||||||
int hc = queryBindHash();
|
BindHash hash = bindHashAlgorithm == null ? new HashCodeBindHash() : new MdBindHash(bindHashAlgorithm);
|
||||||
return new HashQuery(queryPlanKey, hc);
|
queryBindHash(hash);
|
||||||
|
hash.finish();
|
||||||
|
return new HashQuery(queryPlanKey, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package io.ebeaninternal.server.querydefn;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HashCode builder that uses Object.hashCode for computing bind-hashes.
|
||||||
|
* This is a fast and lightweight implementation, but may produce collisions.
|
||||||
|
*
|
||||||
|
* @author Roland Praml, FOCONIS AG
|
||||||
|
*/
|
||||||
|
public class HashCodeBindHash implements BindHash {
|
||||||
|
|
||||||
|
int hashCode;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BindHash update(int intValue) {
|
||||||
|
hashCode = hashCode * 92821 + intValue;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BindHash update(long longValue) {
|
||||||
|
hashCode = hashCode * 92821 + Long.hashCode(longValue);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BindHash update(boolean boolValue) {
|
||||||
|
hashCode = hashCode * 92821 + Boolean.hashCode(boolValue);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BindHash update(Object value) {
|
||||||
|
hashCode = hashCode * 92821 + Objects.hashCode(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finish() {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return obj instanceof HashCodeBindHash && ((HashCodeBindHash) obj).hashCode == hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* Licensed Materials - Property of FOCONIS AG
|
||||||
|
* (C) Copyright FOCONIS AG.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.ebeaninternal.server.querydefn;
|
||||||
|
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind hash that uses a MessageDigest to compute a collision resistent hash.
|
||||||
|
*
|
||||||
|
* @author Roland Praml, FOCONIS AG
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MdBindHash implements BindHash {
|
||||||
|
private MessageDigest md;
|
||||||
|
private byte[] buffer;
|
||||||
|
private int hashCode;
|
||||||
|
|
||||||
|
public MdBindHash(String algorithm) {
|
||||||
|
try {
|
||||||
|
md = MessageDigest.getInstance(algorithm);
|
||||||
|
} catch (NoSuchAlgorithmException nsae) {
|
||||||
|
throw new InternalError(algorithm + " not supported", nsae);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BindHash update(int v) {
|
||||||
|
md.update((byte) (v >>> 24));
|
||||||
|
md.update((byte) (v >>> 16));
|
||||||
|
md.update((byte) (v >>> 8));
|
||||||
|
md.update((byte) (v >>> 0));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BindHash update(long v) {
|
||||||
|
md.update((byte) (v >>> 56));
|
||||||
|
md.update((byte) (v >>> 48));
|
||||||
|
md.update((byte) (v >>> 40));
|
||||||
|
md.update((byte) (v >>> 32));
|
||||||
|
md.update((byte) (v >>> 24));
|
||||||
|
md.update((byte) (v >>> 16));
|
||||||
|
md.update((byte) (v >>> 8));
|
||||||
|
md.update((byte) (v >>> 0));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BindHash update(boolean boolValue) {
|
||||||
|
md.update(boolValue ? (byte) 1 : (byte) 0);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BindHash update(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
md.update((byte) 0);
|
||||||
|
|
||||||
|
// do some special handling for known object types
|
||||||
|
} else if (value instanceof String) {
|
||||||
|
md.update(((String) value).getBytes());
|
||||||
|
|
||||||
|
} else if (value instanceof Long) {
|
||||||
|
update(((Long) value).longValue());
|
||||||
|
|
||||||
|
} else if (value instanceof Double) {
|
||||||
|
double d = ((Double) value).doubleValue();
|
||||||
|
update(Double.doubleToLongBits(d));
|
||||||
|
|
||||||
|
} else if (value instanceof UUID) {
|
||||||
|
UUID uuid = (UUID) value;
|
||||||
|
update(uuid.getLeastSignificantBits());
|
||||||
|
update(uuid.getMostSignificantBits());
|
||||||
|
|
||||||
|
} else if (value instanceof Date) {
|
||||||
|
update(((Date) value).getTime());
|
||||||
|
|
||||||
|
} else if (value instanceof Instant) {
|
||||||
|
update(((Instant) value).getEpochSecond());
|
||||||
|
update(((Instant) value).getNano());
|
||||||
|
|
||||||
|
} else if (value instanceof LocalDate) {
|
||||||
|
update(((LocalDate) value).toEpochDay());
|
||||||
|
|
||||||
|
} else if (value instanceof LocalTime) {
|
||||||
|
update(((LocalTime) value).toSecondOfDay());
|
||||||
|
update(((LocalTime) value).toNanoOfDay());
|
||||||
|
|
||||||
|
} else if (value instanceof LocalDateTime) {
|
||||||
|
update(((LocalDateTime) value).toLocalDate().toEpochDay());
|
||||||
|
update(((LocalDateTime) value).toLocalTime().toSecondOfDay());
|
||||||
|
update(((LocalDateTime) value).toLocalTime().toNanoOfDay());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Fall back to hashCode for all other types
|
||||||
|
updateOther(value);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update all other object. May be overridden to handle joda dates.
|
||||||
|
*/
|
||||||
|
protected void updateOther(Object value) {
|
||||||
|
// Fall back to hashCode for all other types
|
||||||
|
update(value.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finish() {
|
||||||
|
buffer = md.digest();
|
||||||
|
hashCode = Arrays.hashCode(buffer);
|
||||||
|
md = null; // clear memory
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return obj instanceof MdBindHash && Arrays.equals(buffer, ((MdBindHash) obj).buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,8 @@ package io.ebeaninternal.server.expression;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
|
import io.ebeaninternal.server.querydefn.HashCodeBindHash;
|
||||||
|
|
||||||
public class RawExpressionTest extends BaseExpressionTest {
|
public class RawExpressionTest extends BaseExpressionTest {
|
||||||
|
|
||||||
@@ -61,11 +63,17 @@ public class RawExpressionTest extends BaseExpressionTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void assert_queryBindHash_isDifferent(RawExpression exp0, RawExpression exp1) {
|
public void assert_queryBindHash_isDifferent(RawExpression exp0, RawExpression exp1) {
|
||||||
assertThat(exp0.queryBindHash()).isNotEqualTo(exp1.queryBindHash());
|
assertThat(getHash(exp0)).isNotEqualTo(getHash(exp1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assert_queryBindHash_isSame(RawExpression exp0, RawExpression exp1) {
|
public void assert_queryBindHash_isSame(RawExpression exp0, RawExpression exp1) {
|
||||||
assertThat(exp0.queryBindHash()).isEqualTo(exp1.queryBindHash());
|
assertThat(getHash(exp0)).isEqualTo(getHash(exp1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getHash(RawExpression query) {
|
||||||
|
BindHash hash = new HashCodeBindHash();
|
||||||
|
query.queryBindHash(hash);
|
||||||
|
hash.finish();
|
||||||
|
return hash.hashCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+11
-3
@@ -4,6 +4,7 @@ package io.ebeaninternal.server.querydefn;
|
|||||||
import io.ebean.BaseTestCase;
|
import io.ebean.BaseTestCase;
|
||||||
import io.ebean.CacheMode;
|
import io.ebean.CacheMode;
|
||||||
import io.ebean.Ebean;
|
import io.ebean.Ebean;
|
||||||
|
import io.ebeaninternal.api.BindHash;
|
||||||
import io.ebeaninternal.api.SpiQuery;
|
import io.ebeaninternal.api.SpiQuery;
|
||||||
import io.ebeaninternal.server.core.OrmQueryRequest;
|
import io.ebeaninternal.server.core.OrmQueryRequest;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -62,7 +63,7 @@ public class DefaultOrmQueryTest extends BaseTestCase {
|
|||||||
|
|
||||||
prepare(q1, q2);
|
prepare(q1, q2);
|
||||||
assertThat(q1.createQueryPlanKey()).isNotEqualTo(q2.createQueryPlanKey());
|
assertThat(q1.createQueryPlanKey()).isNotEqualTo(q2.createQueryPlanKey());
|
||||||
assertThat(q1.queryBindHash()).isNotEqualTo(q2.queryBindHash());
|
assertThat(getHash(q1)).isNotEqualTo(getHash(q2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -73,7 +74,7 @@ public class DefaultOrmQueryTest extends BaseTestCase {
|
|||||||
|
|
||||||
prepare(q1, q2);
|
prepare(q1, q2);
|
||||||
assertThat(q1.createQueryPlanKey()).isEqualTo(q2.createQueryPlanKey());
|
assertThat(q1.createQueryPlanKey()).isEqualTo(q2.createQueryPlanKey());
|
||||||
assertThat(q1.queryBindHash()).isNotEqualTo(q2.queryBindHash());
|
assertThat(getHash(q1)).isNotEqualTo(getHash(q2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -84,7 +85,7 @@ public class DefaultOrmQueryTest extends BaseTestCase {
|
|||||||
|
|
||||||
prepare(q1, q2);
|
prepare(q1, q2);
|
||||||
assertThat(q1.createQueryPlanKey()).isEqualTo(q2.createQueryPlanKey());
|
assertThat(q1.createQueryPlanKey()).isEqualTo(q2.createQueryPlanKey());
|
||||||
assertThat(q1.queryBindHash()).isEqualTo(q2.queryBindHash());
|
assertThat(getHash(q1)).isEqualTo(getHash(q2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -110,4 +111,11 @@ public class DefaultOrmQueryTest extends BaseTestCase {
|
|||||||
OrmQueryRequest<T> r2 = createQueryRequest(SpiQuery.Type.LIST, q2, null);
|
OrmQueryRequest<T> r2 = createQueryRequest(SpiQuery.Type.LIST, q2, null);
|
||||||
q2.prepare(r2);
|
q2.prepare(r2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getHash(DefaultOrmQuery<Order> query) {
|
||||||
|
BindHash hash = new HashCodeBindHash();
|
||||||
|
query.queryBindHash(hash);
|
||||||
|
hash.finish();
|
||||||
|
return hash.hashCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+58
-28
@@ -3,7 +3,7 @@ package org.tests.cache;
|
|||||||
import io.ebean.BaseTestCase;
|
import io.ebean.BaseTestCase;
|
||||||
import io.ebean.CacheMode;
|
import io.ebean.CacheMode;
|
||||||
import io.ebean.DB;
|
import io.ebean.DB;
|
||||||
import io.ebean.Ebean;
|
import io.ebean.ExpressionList;
|
||||||
import io.ebean.bean.BeanCollection;
|
import io.ebean.bean.BeanCollection;
|
||||||
import io.ebean.cache.ServerCache;
|
import io.ebean.cache.ServerCache;
|
||||||
import org.ebeantest.LoggedSqlCollector;
|
import org.ebeantest.LoggedSqlCollector;
|
||||||
@@ -14,6 +14,7 @@ import org.tests.model.basic.ResetBasicData;
|
|||||||
import org.tests.model.cache.EColAB;
|
import org.tests.model.cache.EColAB;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@@ -26,8 +27,7 @@ public class TestQueryCache extends BaseTestCase {
|
|||||||
new EColAB("02", "10").save();
|
new EColAB("02", "10").save();
|
||||||
|
|
||||||
List<EColAB> list1 =
|
List<EColAB> list1 =
|
||||||
Ebean.getServer(null)
|
DB.find(EColAB.class)
|
||||||
.find(EColAB.class)
|
|
||||||
.setUseQueryCache(true)
|
.setUseQueryCache(true)
|
||||||
.where()
|
.where()
|
||||||
.eq("columnA", "01")
|
.eq("columnA", "01")
|
||||||
@@ -35,8 +35,7 @@ public class TestQueryCache extends BaseTestCase {
|
|||||||
.findList();
|
.findList();
|
||||||
|
|
||||||
List<EColAB> list2 =
|
List<EColAB> list2 =
|
||||||
Ebean.getServer(null)
|
DB.find(EColAB.class)
|
||||||
.find(EColAB.class)
|
|
||||||
.setUseQueryCache(true)
|
.setUseQueryCache(true)
|
||||||
.where()
|
.where()
|
||||||
.eq("columnA", "02")
|
.eq("columnA", "02")
|
||||||
@@ -57,7 +56,7 @@ public class TestQueryCache extends BaseTestCase {
|
|||||||
new EColAB("03", "SingleAttribute").save();
|
new EColAB("03", "SingleAttribute").save();
|
||||||
new EColAB("03", "SingleAttribute").save();
|
new EColAB("03", "SingleAttribute").save();
|
||||||
|
|
||||||
List<String> colA_first = Ebean.getServer(null)
|
List<String> colA_first = DB
|
||||||
.find(EColAB.class)
|
.find(EColAB.class)
|
||||||
.setUseQueryCache(true)
|
.setUseQueryCache(true)
|
||||||
.setDistinct(true)
|
.setDistinct(true)
|
||||||
@@ -66,7 +65,7 @@ public class TestQueryCache extends BaseTestCase {
|
|||||||
.eq("columnB", "SingleAttribute")
|
.eq("columnB", "SingleAttribute")
|
||||||
.findSingleAttributeList();
|
.findSingleAttributeList();
|
||||||
|
|
||||||
List<String> colA_Second = Ebean.getServer(null)
|
List<String> colA_Second = DB
|
||||||
.find(EColAB.class)
|
.find(EColAB.class)
|
||||||
.setUseQueryCache(true)
|
.setUseQueryCache(true)
|
||||||
.setDistinct(true)
|
.setDistinct(true)
|
||||||
@@ -77,7 +76,7 @@ public class TestQueryCache extends BaseTestCase {
|
|||||||
|
|
||||||
assertThat(colA_Second).isSameAs(colA_first);
|
assertThat(colA_Second).isSameAs(colA_first);
|
||||||
|
|
||||||
List<String> colA_NotDistinct = Ebean.getServer(null)
|
List<String> colA_NotDistinct = DB
|
||||||
.find(EColAB.class)
|
.find(EColAB.class)
|
||||||
.setUseQueryCache(true)
|
.setUseQueryCache(true)
|
||||||
.select("columnA")
|
.select("columnA")
|
||||||
@@ -89,7 +88,7 @@ public class TestQueryCache extends BaseTestCase {
|
|||||||
|
|
||||||
// ensure that findCount & findSingleAttribute use different
|
// ensure that findCount & findSingleAttribute use different
|
||||||
// slots in cache. If not a "Cannot cast List to int" should happen.
|
// slots in cache. If not a "Cannot cast List to int" should happen.
|
||||||
int count = Ebean.getServer(null)
|
int count = DB
|
||||||
.find(EColAB.class)
|
.find(EColAB.class)
|
||||||
.setUseQueryCache(true)
|
.setUseQueryCache(true)
|
||||||
.select("columnA")
|
.select("columnA")
|
||||||
@@ -107,13 +106,13 @@ public class TestQueryCache extends BaseTestCase {
|
|||||||
|
|
||||||
LoggedSqlCollector.start();
|
LoggedSqlCollector.start();
|
||||||
|
|
||||||
int count0 = Ebean.find(EColAB.class)
|
int count0 = DB.find(EColAB.class)
|
||||||
.setUseQueryCache(CacheMode.ON)
|
.setUseQueryCache(CacheMode.ON)
|
||||||
.where()
|
.where()
|
||||||
.eq("columnB", "count")
|
.eq("columnB", "count")
|
||||||
.findCount();
|
.findCount();
|
||||||
|
|
||||||
int count1 = Ebean.find(EColAB.class)
|
int count1 = DB.find(EColAB.class)
|
||||||
.setUseQueryCache(CacheMode.ON)
|
.setUseQueryCache(CacheMode.ON)
|
||||||
.where()
|
.where()
|
||||||
.eq("columnB", "count")
|
.eq("columnB", "count")
|
||||||
@@ -126,7 +125,7 @@ public class TestQueryCache extends BaseTestCase {
|
|||||||
|
|
||||||
// and now, ensure that we hit the database
|
// and now, ensure that we hit the database
|
||||||
LoggedSqlCollector.start();
|
LoggedSqlCollector.start();
|
||||||
int count2 = Ebean.find(EColAB.class)
|
int count2 = DB.find(EColAB.class)
|
||||||
.setUseQueryCache(CacheMode.OFF)
|
.setUseQueryCache(CacheMode.OFF)
|
||||||
.where()
|
.where()
|
||||||
.eq("columnB", "count")
|
.eq("columnB", "count")
|
||||||
@@ -142,13 +141,13 @@ public class TestQueryCache extends BaseTestCase {
|
|||||||
|
|
||||||
LoggedSqlCollector.start();
|
LoggedSqlCollector.start();
|
||||||
|
|
||||||
int count0 = Ebean.find(EColAB.class)
|
int count0 = DB.find(EColAB.class)
|
||||||
.setUseQueryCache(CacheMode.ON)
|
.setUseQueryCache(CacheMode.ON)
|
||||||
.where()
|
.where()
|
||||||
.eq("columnB", "abc")
|
.eq("columnB", "abc")
|
||||||
.findCount();
|
.findCount();
|
||||||
|
|
||||||
int count1 = Ebean.find(EColAB.class)
|
int count1 = DB.find(EColAB.class)
|
||||||
.setUseQueryCache(CacheMode.ON)
|
.setUseQueryCache(CacheMode.ON)
|
||||||
.where()
|
.where()
|
||||||
.eq("columnB", "def")
|
.eq("columnB", "def")
|
||||||
@@ -167,13 +166,13 @@ public class TestQueryCache extends BaseTestCase {
|
|||||||
|
|
||||||
LoggedSqlCollector.start();
|
LoggedSqlCollector.start();
|
||||||
|
|
||||||
int count0 = Ebean.find(EColAB.class)
|
int count0 = DB.find(EColAB.class)
|
||||||
.setUseQueryCache(CacheMode.ON)
|
.setUseQueryCache(CacheMode.ON)
|
||||||
.where()
|
.where()
|
||||||
.eq("columnB", "uvw")
|
.eq("columnB", "uvw")
|
||||||
.findCount();
|
.findCount();
|
||||||
|
|
||||||
int count1 = Ebean.find(EColAB.class)
|
int count1 = DB.find(EColAB.class)
|
||||||
.setUseQueryCache(CacheMode.PUT)
|
.setUseQueryCache(CacheMode.PUT)
|
||||||
.where()
|
.where()
|
||||||
.eq("columnB", "uvw")
|
.eq("columnB", "uvw")
|
||||||
@@ -193,13 +192,13 @@ public class TestQueryCache extends BaseTestCase {
|
|||||||
|
|
||||||
LoggedSqlCollector.start();
|
LoggedSqlCollector.start();
|
||||||
|
|
||||||
int count0 = Ebean.find(EColAB.class)
|
int count0 = DB.find(EColAB.class)
|
||||||
.setUseQueryCache(CacheMode.PUT)
|
.setUseQueryCache(CacheMode.PUT)
|
||||||
.where()
|
.where()
|
||||||
.eq("columnB", "xyz")
|
.eq("columnB", "xyz")
|
||||||
.findCount();
|
.findCount();
|
||||||
|
|
||||||
int count1 = Ebean.find(EColAB.class)
|
int count1 = DB.find(EColAB.class)
|
||||||
.setUseQueryCache(CacheMode.ON)
|
.setUseQueryCache(CacheMode.ON)
|
||||||
.where()
|
.where()
|
||||||
.eq("columnB", "xyz")
|
.eq("columnB", "xyz")
|
||||||
@@ -214,26 +213,26 @@ public class TestQueryCache extends BaseTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void test() {
|
public void testReadOnlyFind() {
|
||||||
|
|
||||||
ResetBasicData.reset();
|
ResetBasicData.reset();
|
||||||
|
|
||||||
ServerCache customerCache = Ebean.getServerCacheManager().getQueryCache(Customer.class);
|
ServerCache customerCache = DB.getServerCacheManager().getQueryCache(Customer.class);
|
||||||
customerCache.clear();
|
customerCache.clear();
|
||||||
|
|
||||||
List<Customer> list = Ebean.find(Customer.class).setUseQueryCache(true).setReadOnly(true).where()
|
List<Customer> list = DB.find(Customer.class).setUseQueryCache(true).setReadOnly(true).where()
|
||||||
.ilike("name", "Rob").findList();
|
.ilike("name", "Rob").findList();
|
||||||
|
|
||||||
BeanCollection<Customer> bc = (BeanCollection<Customer>) list;
|
BeanCollection<Customer> bc = (BeanCollection<Customer>) list;
|
||||||
Assert.assertTrue(bc.isReadOnly());
|
Assert.assertTrue(bc.isReadOnly());
|
||||||
Assert.assertFalse(bc.isEmpty());
|
Assert.assertFalse(bc.isEmpty());
|
||||||
Assert.assertTrue(!list.isEmpty());
|
Assert.assertTrue(!list.isEmpty());
|
||||||
Assert.assertTrue(Ebean.getBeanState(list.get(0)).isReadOnly());
|
Assert.assertTrue(DB.getBeanState(list.get(0)).isReadOnly());
|
||||||
|
|
||||||
List<Customer> list2 = Ebean.find(Customer.class).setUseQueryCache(true).setReadOnly(true).where()
|
List<Customer> list2 = DB.find(Customer.class).setUseQueryCache(true).setReadOnly(true).where()
|
||||||
.ilike("name", "Rob").findList();
|
.ilike("name", "Rob").findList();
|
||||||
|
|
||||||
List<Customer> list2B = Ebean.find(Customer.class).setUseQueryCache(true)
|
List<Customer> list2B = DB.find(Customer.class).setUseQueryCache(true)
|
||||||
// .setReadOnly(true)
|
// .setReadOnly(true)
|
||||||
.where().ilike("name", "Rob").findList();
|
.where().ilike("name", "Rob").findList();
|
||||||
|
|
||||||
@@ -245,7 +244,7 @@ public class TestQueryCache extends BaseTestCase {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
List<Customer> list3 = Ebean.find(Customer.class).setUseQueryCache(true).setReadOnly(false).where()
|
List<Customer> list3 = DB.find(Customer.class).setUseQueryCache(true).setReadOnly(false).where()
|
||||||
.ilike("name", "Rob").findList();
|
.ilike("name", "Rob").findList();
|
||||||
|
|
||||||
Assert.assertNotSame(list, list3);
|
Assert.assertNotSame(list, list3);
|
||||||
@@ -269,13 +268,13 @@ public class TestQueryCache extends BaseTestCase {
|
|||||||
|
|
||||||
LoggedSqlCollector.start();
|
LoggedSqlCollector.start();
|
||||||
|
|
||||||
List<Integer> colA_first = Ebean.find(EColAB.class)
|
List<Integer> colA_first = DB.find(EColAB.class)
|
||||||
.setUseQueryCache(CacheMode.ON)
|
.setUseQueryCache(CacheMode.ON)
|
||||||
.where()
|
.where()
|
||||||
.eq("columnB", "someId")
|
.eq("columnB", "someId")
|
||||||
.findIds();
|
.findIds();
|
||||||
|
|
||||||
List<Integer> colA_second = Ebean.find(EColAB.class)
|
List<Integer> colA_second = DB.find(EColAB.class)
|
||||||
.setUseQueryCache(CacheMode.ON)
|
.setUseQueryCache(CacheMode.ON)
|
||||||
.where()
|
.where()
|
||||||
.eq("columnB", "someId")
|
.eq("columnB", "someId")
|
||||||
@@ -289,7 +288,7 @@ public class TestQueryCache extends BaseTestCase {
|
|||||||
|
|
||||||
// and now, ensure that we hit the database
|
// and now, ensure that we hit the database
|
||||||
LoggedSqlCollector.start();
|
LoggedSqlCollector.start();
|
||||||
colA_second = Ebean.find(EColAB.class)
|
colA_second = DB.find(EColAB.class)
|
||||||
.setUseQueryCache(CacheMode.PUT)
|
.setUseQueryCache(CacheMode.PUT)
|
||||||
.where()
|
.where()
|
||||||
.eq("columnB", "someId")
|
.eq("columnB", "someId")
|
||||||
@@ -299,4 +298,35 @@ public class TestQueryCache extends BaseTestCase {
|
|||||||
assertThat(sql).hasSize(1);
|
assertThat(sql).hasSize(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findCountDifferentQueriesBit() {
|
||||||
|
DB.getDefault().getPluginApi().getServerCacheManager().clearAll();
|
||||||
|
differentFindCount(q->q.bitwiseAny("id",1), q->q.bitwiseAny("id",0));
|
||||||
|
differentFindCount(q->q.bitwiseAll("id",1), q->q.bitwiseAll("id",0));
|
||||||
|
// differentFindCount(q->q.bitwiseNot("id",1), q->q.bitwiseNot("id",0)); NOT 1 == AND 1 = 0
|
||||||
|
differentFindCount(q->q.bitwiseAnd("id",1, 0), q->q.bitwiseAnd("id",1, 1));
|
||||||
|
|
||||||
|
differentFindCount(q->q.bitwiseAnd("id",2, 0), q->q.bitwiseAnd("id",4, 0));
|
||||||
|
differentFindCount(q->q.bitwiseAnd("id",2, 1), q->q.bitwiseAnd("id",4, 1));
|
||||||
|
// Will produce hash collision
|
||||||
|
differentFindCount(q->q.bitwiseAnd("id",10, 0), q->q.bitwiseAnd("id",0, 928210));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void differentFindCount(Consumer<ExpressionList<EColAB>> q0, Consumer<ExpressionList<EColAB>> q1) {
|
||||||
|
LoggedSqlCollector.start();
|
||||||
|
|
||||||
|
ExpressionList<EColAB> el0 = DB.find(EColAB.class).setUseQueryCache(CacheMode.ON).where();
|
||||||
|
q0.accept(el0);
|
||||||
|
el0.findCount();
|
||||||
|
|
||||||
|
ExpressionList<EColAB> el1 = DB.find(EColAB.class).setUseQueryCache(CacheMode.ON).where();
|
||||||
|
q1.accept(el1);
|
||||||
|
el1.findCount();
|
||||||
|
|
||||||
|
List<String> sql = LoggedSqlCollector.stop();
|
||||||
|
|
||||||
|
assertThat(sql).hasSize(2); // different queries
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user