OPENJPA-2733 OPENJPA-2785 fix broken spring data usage.

spring-data potentially does something unspecified.
This hack now prevents duplicate ParameterExpressions with the same name
while not having to implement equals + hashCode for it - which makes Spring happy.
This commit is contained in:
Mark Struberg 2019-04-10 16:05:21 +02:00
parent d8ddf87a47
commit f9b59689d4
3 changed files with 39 additions and 14 deletions

View File

@ -618,6 +618,10 @@ public class TestSubqueries extends CriteriaTest {
cleanCustomerAndOrder();
}
/**
* Test 2 different ParameterExpression instances which both have the same name.
* They should
*/
public void testSubquery25() {
em.getTransaction().begin();

View File

@ -224,10 +224,18 @@ class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>, AliasContext {
* Registers the given parameter.
*/
void registerParameter(ParameterExpressionImpl<?> p) {
if (!_params.containsKey(p)) {
p.setIndex(_params.size());
_params.put(p, p.getJavaType());
for (Object k : _params.keySet()) {
if (p.paramEquals(k)) {
// If a named ParameterExpressin did already get registered
// with that exact name, then we do ignore it.
// If we do a query.setParameter("someParamName", Bla)
// then it must uniquely identify a Parameter.
return;
}
}
p.setIndex(_params.size());
_params.put(p, p.getJavaType());
}
@Override

View File

@ -24,6 +24,7 @@ import javax.persistence.criteria.ParameterExpression;
import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.kernel.exps.Value;
import org.apache.openjpa.lib.util.OrderedMap;
import org.apache.openjpa.util.InternalException;
/**
@ -109,13 +110,25 @@ class ParameterExpressionImpl<T> extends ExpressionImpl<T>
: factory.newParameter(paramKey, clzz);
int index = _name != null
? q.getParameterTypes().indexOf(this)
? findIndexWithSameName(q)
: _index;
param.setIndex(index);
return param;
}
private int findIndexWithSameName(CriteriaQueryImpl<?> q) {
OrderedMap<Object, Class<?>> parameterTypes = q.getParameterTypes();
int i = 0;
for (Object k : parameterTypes.keySet()) {
if (paramEquals(k)) {
return i;
}
i++;
}
return -1;
}
@Override
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, ":", _name == null ? "param" : _name);
@ -126,8 +139,7 @@ class ParameterExpressionImpl<T> extends ExpressionImpl<T>
return getJavaType();
}
@Override
public boolean equals(Object o) {
public boolean paramEquals(Object o) {
if (this == o)
return true;
@ -150,14 +162,15 @@ class ParameterExpressionImpl<T> extends ExpressionImpl<T>
}
@Override
public int hashCode() {
int result = _name != null ? _name.hashCode() : 0;
if (_name == null) {
// if name is given, then we ignore the index
result = 31 * result + _index;
public boolean equals(Object o) {
if (this == o) {
return true;
}
result = 31 * result + (getParameterType() != null ? getParameterType().hashCode() : 0);
result = 31 * result + (value != null ? value.hashCode() : 0);
return result;
return false;
}
@Override
public int hashCode() {
return super.hashCode();
}
}