DATAJPA-424 - Fixed alias detection in manually defined queries using SpEL.
ExpressionBasedStringQuery now resolves and evaluates SpEL expressions of the actual query in the constructor and passes the resolved query to the StringQuery constructor. This enables the alias detection mechanism to work properly. Original pull request: #51
This commit is contained in:
committed by
Oliver Gierke
parent
df55a8525d
commit
6a26db86cf
@@ -37,9 +37,6 @@ import org.springframework.util.Assert;
|
||||
class ExpressionBasedStringQuery extends StringQuery {
|
||||
|
||||
private static final String ENTITY_NAME = "entityName";
|
||||
private final JpaEntityMetadata<?> metadata;
|
||||
|
||||
private String parsedQuery;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ExpressionBasedStringQuery} for the given query and {@link EntityMetadata}.
|
||||
@@ -48,28 +45,18 @@ class ExpressionBasedStringQuery extends StringQuery {
|
||||
* @param metadata must not be {@literal null}.
|
||||
*/
|
||||
public ExpressionBasedStringQuery(String query, JpaEntityMetadata<?> metadata) {
|
||||
|
||||
super(query);
|
||||
Assert.notNull(metadata, "JpaEntityMetadata must not be null!");
|
||||
this.metadata = metadata;
|
||||
super(renderQueryIfExpressionOrReturnQuery(query, metadata));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.repository.query.StringQuery#getQuery()
|
||||
/**
|
||||
* @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}.
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getQuery() {
|
||||
private static String renderQueryIfExpressionOrReturnQuery(String query, JpaEntityMetadata<?> metadata) {
|
||||
|
||||
if (parsedQuery == null) {
|
||||
String rawQuery = super.getQuery();
|
||||
this.parsedQuery = renderQueryIfExpressionOrReturnQuery(rawQuery);
|
||||
}
|
||||
|
||||
return this.parsedQuery;
|
||||
}
|
||||
|
||||
private String renderQueryIfExpressionOrReturnQuery(String query) {
|
||||
Assert.notNull(query, "query must not be null!");
|
||||
Assert.notNull(metadata, "metadata must not be null!");
|
||||
|
||||
if (!containsExpression(query)) {
|
||||
return query;
|
||||
|
||||
@@ -25,6 +25,9 @@ import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.sample.ConcreteType1;
|
||||
import org.springframework.data.jpa.domain.sample.ConcreteType2;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
@@ -68,4 +71,19 @@ public class MappedTypeRepositoryIntegrationTests {
|
||||
assertThat(concretes1.size(), is(1));
|
||||
assertThat(concretes2.size(), is(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-424
|
||||
*/
|
||||
@Test
|
||||
public void supportForPaginationCustomQueryMethodsWithEntityExpression() {
|
||||
|
||||
concreteRepository1.save(new ConcreteType1("foo"));
|
||||
concreteRepository2.save(new ConcreteType2("foo"));
|
||||
|
||||
Page<ConcreteType2> page = concreteRepository2.findByAttribute1Custom("foo", new PageRequest(0, 10,
|
||||
Sort.Direction.DESC, "attribute1"));
|
||||
|
||||
assertThat(page.getNumberOfElements(), is(1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,4 +48,18 @@ public class ExpressionBasedStringQueryUnitTests {
|
||||
StringQuery query = new ExpressionBasedStringQuery(source, metadata);
|
||||
assertThat(query.getQuery(), is("select from User u where u.firstname like :firstname"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @DATAJPA-424
|
||||
*/
|
||||
@Test
|
||||
public void renderAliasInExpressionQueryCorrectly() {
|
||||
|
||||
when(metadata.getEntityName()).thenReturn("User");
|
||||
|
||||
StringQuery query = new ExpressionBasedStringQuery("select u from #{#entityName} u", metadata);
|
||||
|
||||
assertThat(query.getAlias(), is("u"));
|
||||
assertThat(query.getQuery(), is("select u from User u"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,12 @@ package org.springframework.data.jpa.repository.sample;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.domain.sample.AbstractMappedType;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
/**
|
||||
* @author Thomas Darimont
|
||||
@@ -28,4 +31,7 @@ public interface MappedTypeRepository<T extends AbstractMappedType> extends JpaR
|
||||
|
||||
@Query("from #{#entityName} t where t.attribute1=?1")
|
||||
List<T> findAllByAttribute1(String attribute1);
|
||||
|
||||
@Query("SELECT o FROM #{#entityName} o where o.attribute1=:attribute1")
|
||||
Page<T> findByAttribute1Custom(@Param("attribute1") String attribute1, Pageable pageable);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user