DATADOC-99 - ParameterExpressionProvider now uses parameter type instead of handed in type if assignable.
JpaQueryCreator hands Comparable into ParameterExpressionProvider to create ParameterExpression instances for Comparables. The ParameterExpressionProvider in turn now inspects the actual Parameter type and hand this one into the builder in case it's assignable (read: more concrete) to the given type requested.
This commit is contained in:
@@ -40,6 +40,7 @@ import org.springframework.data.repository.query.parser.Part;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
import org.springframework.data.repository.query.parser.Property;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Query creator to create a {@link CriteriaQuery} from a {@link PartTree}.
|
||||
@@ -233,7 +234,7 @@ public class JpaQueryCreator extends AbstractQueryCreator<CriteriaQuery<Object>,
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class ParameterExpressionProvider {
|
||||
static class ParameterExpressionProvider {
|
||||
|
||||
private final CriteriaBuilder builder;
|
||||
private final Iterator<Parameter> parameters;
|
||||
@@ -285,10 +286,12 @@ public class JpaQueryCreator extends AbstractQueryCreator<CriteriaQuery<Object>,
|
||||
* @param type must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> ParameterExpression<T> next(Class<T> type) {
|
||||
|
||||
parameters.next();
|
||||
return next(type, null);
|
||||
Parameter parameter = parameters.next();
|
||||
Class<?> typeToUse = ClassUtils.isAssignable(type, parameter.getType()) ? parameter.getType() : type;
|
||||
return (ParameterExpression<T>) next(typeToUse, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -299,14 +302,13 @@ public class JpaQueryCreator extends AbstractQueryCreator<CriteriaQuery<Object>,
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> ParameterExpression<T> next(Class<T> type, String name) {
|
||||
|
||||
Assert.notNull(type);
|
||||
|
||||
ParameterExpression<?> expression = name == null ? builder.parameter(type) : builder.parameter(type, name);
|
||||
ParameterExpression<T> expression = name == null ? builder.parameter(type) : builder.parameter(type, name);
|
||||
expressions.add(expression);
|
||||
return (ParameterExpression<T>) expression;
|
||||
return expression;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.springframework.data.jpa.repository.query;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.criteria.ParameterExpression;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.data.jpa.domain.sample.User;
|
||||
import org.springframework.data.jpa.repository.query.JpaQueryCreator.ParameterExpressionProvider;
|
||||
import org.springframework.data.repository.query.Parameters;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link ParameterExpressionProvider}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
public class ParameterExpressionProviderTests {
|
||||
|
||||
@PersistenceContext
|
||||
EntityManager em;
|
||||
|
||||
/**
|
||||
* @see DATADOC-99
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void createsParameterExpressionWithMostConcreteType() throws Exception {
|
||||
|
||||
Method method = SampleRepository.class.getMethod("findByIdGreaterThan", int.class);
|
||||
Parameters parameters = new Parameters(method);
|
||||
|
||||
ParameterExpressionProvider provider = new ParameterExpressionProvider(em.getCriteriaBuilder(), parameters);
|
||||
ParameterExpression<? extends Comparable> expression = provider.next(Comparable.class);
|
||||
assertThat(expression.getParameterType(), is(typeCompatibleWith(int.class)));
|
||||
}
|
||||
|
||||
interface SampleRepository {
|
||||
|
||||
User findByIdGreaterThan(int id);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user