@@ -37,7 +37,6 @@ import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ConcurrentLruCache;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Base class for {@link String} based JPA queries.
|
||||
@@ -71,7 +70,6 @@ abstract class AbstractStringBasedJpaQuery extends AbstractJpaQuery {
|
||||
* @param method must not be {@literal null}.
|
||||
* @param em must not be {@literal null}.
|
||||
* @param queryString must not be {@literal null}.
|
||||
* @param countQuery can be {@literal null} if not defined.
|
||||
* @param queryConfiguration must not be {@literal null}.
|
||||
*/
|
||||
AbstractStringBasedJpaQuery(JpaQueryMethod method, EntityManager em, String queryString,
|
||||
|
||||
@@ -175,6 +175,10 @@ abstract class QueryRenderer implements QueryTokenStream {
|
||||
return EmptyQueryRenderer.INSTANCE;
|
||||
}
|
||||
|
||||
if (!(tokenStream instanceof QueryRenderer)) {
|
||||
tokenStream = QueryRenderer.from(tokenStream);
|
||||
}
|
||||
|
||||
if (tokenStream.isExpression()) {
|
||||
return (QueryRenderer) tokenStream;
|
||||
}
|
||||
@@ -192,6 +196,10 @@ abstract class QueryRenderer implements QueryTokenStream {
|
||||
return EmptyQueryRenderer.INSTANCE;
|
||||
}
|
||||
|
||||
if (!(tokenStream instanceof QueryRenderer)) {
|
||||
tokenStream = QueryRenderer.from(tokenStream);
|
||||
}
|
||||
|
||||
if (!tokenStream.isExpression()) {
|
||||
return (QueryRenderer) tokenStream;
|
||||
}
|
||||
@@ -323,6 +331,12 @@ abstract class QueryRenderer implements QueryTokenStream {
|
||||
public boolean isExpression() {
|
||||
return !nested.isEmpty() && nested.get(nested.size() - 1).isExpression();
|
||||
}
|
||||
|
||||
public Stream<QueryRenderer> renderers() {
|
||||
return nested.stream()
|
||||
.flatMap(renderer -> renderer instanceof CompositeRenderer ? ((CompositeRenderer) renderer).renderers()
|
||||
: Stream.of(renderer));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,9 +32,12 @@ Support for string-based queries covers both, JPQL queries(`@Query`) and native
|
||||
|
||||
==== JPQL Queries
|
||||
|
||||
When using <<projections.dtos,Class-based projections>> with JPQL, you must use *constructor expressions* in your JPQL query, e.g. `SELECT new com.example.NamesOnly(u.firstname, u.lastname) from User u`.
|
||||
JPA's mechanism to return <<projections.dtos,Class-based projections>> using JPQL is *constructor expressions*.
|
||||
Therefore, your query must define a constructor expression such as `SELECT new com.example.NamesOnly(u.firstname, u.lastname) from User u`.
|
||||
(Note the usage of a FQDN for the DTO type!) This JPQL expression can be used in `@Query` annotations as well where you define any named queries.
|
||||
As a workaround you may use named queries with `ResultSetMapping` or the Hibernate-specific javadoc:{hibernatejavadocurl}org.hibernate.query.ResultListTransformer[]
|
||||
As a workaround you may use named queries with `ResultSetMapping` or the Hibernate-specific javadoc:{hibernatejavadocurl}org.hibernate.query.ResultListTransformer[].
|
||||
|
||||
Spring Data JPA can aid with rewriting your query to a constructor expression if your query selects the primary entity or a list of select items.
|
||||
|
||||
===== DTO Projection JPQL Query Rewriting
|
||||
|
||||
|
||||
Reference in New Issue
Block a user