mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
FIX: Pairs must not be modified by query (#1539)
* FIX: Pairs must not be modified by query * Modification can also occur on inValues. * fixed tests * removed obsolete line
This commit is contained in:
committed by
Rob Bygrave
parent
01d9dd3fe8
commit
105f08cca1
@@ -1,6 +1,7 @@
|
||||
package io.ebean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -125,7 +126,7 @@ public class Pairs {
|
||||
* Return all the value pairs.
|
||||
*/
|
||||
public List<Entry> getEntries() {
|
||||
return entries;
|
||||
return Collections.unmodifiableList(entries);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,7 @@ public class NaturalKeyQueryData<T> {
|
||||
private List<Pairs.Entry> inPairs;
|
||||
|
||||
// IN clause - only one allowed
|
||||
private Collection<?> inValues;
|
||||
private List<Object> inValues;
|
||||
private String inProperty;
|
||||
|
||||
// normal EQ expressions
|
||||
@@ -52,36 +52,36 @@ public class NaturalKeyQueryData<T> {
|
||||
/**
|
||||
* Match for In Pairs expression. We only allow one IN clause.
|
||||
*/
|
||||
public boolean matchInPairs(Pairs pairs) {
|
||||
public List<Pairs.Entry> matchInPairs(String property0, String property1, List<Pairs.Entry> inPairs) {
|
||||
if (hasIn) {
|
||||
// only 1 IN allowed (to project naturalIds)
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
if (matchProperty(pairs.getProperty0()) && matchProperty(pairs.getProperty1())) {
|
||||
if (matchProperty(property0) && matchProperty(property1)) {
|
||||
this.hasIn = true;
|
||||
this.inProperty0 = pairs.getProperty0();
|
||||
this.inProperty1 = pairs.getProperty1();
|
||||
this.inPairs = pairs.getEntries();
|
||||
return true;
|
||||
this.inProperty0 = property0;
|
||||
this.inProperty1 = property1;
|
||||
this.inPairs = new ArrayList<>(inPairs); // will be modified
|
||||
return this.inPairs;
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Match for IN expression. We only allow one IN clause.
|
||||
*/
|
||||
public boolean matchIn(String propName, Collection<?> sourceValues) {
|
||||
public List<Object> matchIn(String propName, List<Object> sourceValues) {
|
||||
if (hasIn) {
|
||||
// only 1 IN allowed (to project naturalIds)
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
if (matchProperty(propName)) {
|
||||
this.hasIn = true;
|
||||
this.inProperty = propName;
|
||||
this.inValues = sourceValues;
|
||||
return true;
|
||||
this.inValues = new ArrayList<>(sourceValues);
|
||||
return this.inValues;
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -48,8 +48,16 @@ class InExpression extends AbstractExpression {
|
||||
|
||||
@Override
|
||||
public boolean naturalKey(NaturalKeyQueryData<?> data) {
|
||||
// can't use naturalKey cache for NOT IN
|
||||
return !not && data.matchIn(propName, bindValues);
|
||||
// can't use naturalKey cache for NOT IN or if multi values are used
|
||||
if (not || multiValueSupported) {
|
||||
return false;
|
||||
}
|
||||
List<Object> copy = data.matchIn(propName, bindValues);
|
||||
if (copy == null) {
|
||||
return false;
|
||||
}
|
||||
bindValues = copy;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebean.Pairs;
|
||||
import io.ebean.Pairs.Entry;
|
||||
import io.ebean.event.BeanQueryRequest;
|
||||
import io.ebeaninternal.api.NaturalKeyQueryData;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
@@ -15,11 +16,9 @@ class InPairsExpression extends AbstractExpression {
|
||||
|
||||
private final boolean not;
|
||||
|
||||
private final Pairs pairs;
|
||||
|
||||
private final String property0, property1;
|
||||
|
||||
private final List<Pairs.Entry> entries;
|
||||
private List<Pairs.Entry> entries;
|
||||
|
||||
private boolean multiValueSupported;
|
||||
|
||||
@@ -31,9 +30,9 @@ class InPairsExpression extends AbstractExpression {
|
||||
|
||||
InPairsExpression(Pairs pairs, boolean not) {
|
||||
super(pairs.getProperty0());
|
||||
this.pairs = pairs;
|
||||
this.property0 = pairs.getProperty0();
|
||||
this.property1 = pairs.getProperty1();
|
||||
// the entries might be modified on cache hit.
|
||||
this.entries = pairs.getEntries();
|
||||
this.not = not;
|
||||
this.separator = pairs.getConcatSeparator();
|
||||
@@ -42,7 +41,15 @@ class InPairsExpression extends AbstractExpression {
|
||||
|
||||
@Override
|
||||
public boolean naturalKey(NaturalKeyQueryData<?> data) {
|
||||
return !not && data.matchInPairs(pairs);
|
||||
if (not) {
|
||||
return false;
|
||||
}
|
||||
List<Entry> copy = data.matchInPairs(property0, property1, entries);
|
||||
if (copy == null) {
|
||||
return false;
|
||||
}
|
||||
entries = copy;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user