DATAJPA-1163 - Evaluate expression "#{#entityName}" in count queries.

SpEL expressions based on the entityName are now supported in count queries.

Original pull request: #283.
This commit is contained in:
Tom Hombergs
2018-07-18 21:27:39 +02:00
committed by Jens Schauder
parent c023869f93
commit 6513385812
4 changed files with 39 additions and 1 deletions

View File

@@ -34,6 +34,7 @@ import org.springframework.util.Assert;
* @author Oliver Gierke
* @author Thomas Darimont
* @author Jens Schauder
* @author Tom Hombergs
*/
abstract class AbstractStringBasedJpaQuery extends AbstractJpaQuery {
@@ -63,7 +64,9 @@ abstract class AbstractStringBasedJpaQuery extends AbstractJpaQuery {
this.evaluationContextProvider = evaluationContextProvider;
this.query = new ExpressionBasedStringQuery(queryString, method.getEntityInformation(), parser);
this.countQuery = query.deriveCountQuery(method.getCountQuery(), method.getCountQueryProjection());
DeclaredQuery countQuery = query.deriveCountQuery(method.getCountQuery(), method.getCountQueryProjection());
this.countQuery = ExpressionBasedStringQuery.from(countQuery, method.getEntityInformation(), parser);
this.parser = parser;

View File

@@ -34,6 +34,7 @@ import org.springframework.util.Assert;
*
* @author Thomas Darimont
* @author Oliver Gierke
* @author Tom Hombergs
*/
class ExpressionBasedStringQuery extends StringQuery {
@@ -59,6 +60,19 @@ class ExpressionBasedStringQuery extends StringQuery {
super(renderQueryIfExpressionOrReturnQuery(query, metadata, parser));
}
/**
* Creates an {@link ExpressionBasedStringQuery} from a given {@link DeclaredQuery}.
*
* @param query the original query. Must not be {@literal null}.
* @param metadata the {@link JpaEntityMetadata} for the given entity. Must not be {@literal null}.
* @param parser Parser for resolving SpEL expressions. Must not be {@literal null}.
* @return A query supporting SpEL expressions.
*/
public static ExpressionBasedStringQuery from(DeclaredQuery query, JpaEntityMetadata metadata,
SpelExpressionParser parser) {
return new ExpressionBasedStringQuery(query.getQueryString(), metadata, parser);
}
/**
* @param query, the query expression potentially containing a SpEL expression. Must not be {@literal null}.}
* @param metadata the {@link JpaEntityMetadata} for the given entity. Must not be {@literal null}.

View File

@@ -58,6 +58,7 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
* @author Oliver Gierke
* @author Thomas Darimont
* @author Jens Schauder
* @author Tom Hombergs
*/
@RunWith(MockitoJUnitRunner.Silent.class)
public class SimpleJpaQueryUnitTests {
@@ -229,6 +230,22 @@ public class SimpleJpaQueryUnitTests {
.isThrownBy(() -> createJpaQuery(illegalMethod));
}
@Test // DATAJPA-1163
public void resolvesExpressionInCountQuery() throws Exception {
when(em.createQuery(Mockito.anyString())).thenReturn(query);
Method method = UserRepository.class.getMethod("findAllWithExpressionInCountQuery", Pageable.class);
JpaQueryMethod queryMethod = new JpaQueryMethod(method, metadata, factory, extractor);
AbstractJpaQuery jpaQuery = new SimpleJpaQuery(queryMethod, em, "select u from User u", EVALUATION_CONTEXT_PROVIDER,
PARSER);
jpaQuery.createCountQuery(new Object[] { PageRequest.of(1, 10) });
verify(em).createQuery(eq("select u from User u"));
verify(em).createQuery(eq("select count(u.id) from User u"), eq(Long.class));
}
private AbstractJpaQuery createJpaQuery(Method method) {
JpaQueryMethod queryMethod = new JpaQueryMethod(method, metadata, factory, extractor);

View File

@@ -556,6 +556,10 @@ public interface UserRepository
// DATAJPA-1334
List<NameOnlyDto> findByNamedQueryWithConstructorExpression();
// DATAJPA-1163
@Query(value = "select u from #{#entityName} u", countQuery = "select count(u.id) from #{#entityName} u")
List<User> findAllWithExpressionInCountQuery(Pageable pageable);
interface RolesAndFirstname {
String getFirstname();