Skip to content

Commit 61a1a8c

Browse files
committed
Fix potential class-cast exception.
See #3895
1 parent 64d5e70 commit 61a1a8c

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryRenderer.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,10 @@ public static QueryRenderer expression(QueryTokenStream tokenStream) {
190190
return EmptyQueryRenderer.INSTANCE;
191191
}
192192

193+
if (!(tokenStream instanceof QueryRenderer)) {
194+
tokenStream = QueryRenderer.from(tokenStream);
195+
}
196+
193197
if (tokenStream.isExpression()) {
194198
return (QueryRenderer) tokenStream;
195199
}
@@ -207,6 +211,10 @@ public static QueryRenderer inline(QueryTokenStream tokenStream) {
207211
return EmptyQueryRenderer.INSTANCE;
208212
}
209213

214+
if (!(tokenStream instanceof QueryRenderer)) {
215+
tokenStream = QueryRenderer.from(tokenStream);
216+
}
217+
210218
if (!tokenStream.isExpression()) {
211219
return (QueryRenderer) tokenStream;
212220
}
@@ -341,6 +349,12 @@ public int size() {
341349
public boolean isExpression() {
342350
return !nested.isEmpty() && nested.get(nested.size() - 1).isExpression();
343351
}
352+
353+
public Stream<QueryRenderer> renderers() {
354+
return nested.stream()
355+
.flatMap(renderer -> renderer instanceof CompositeRenderer ? ((CompositeRenderer) renderer).renderers()
356+
: Stream.of(renderer));
357+
}
344358
}
345359

346360
/**

src/main/antora/modules/ROOT/pages/repositories/projections.adoc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,12 @@ Support for string-based queries covers both, JPQL queries(`@Query`) and native
3232

3333
==== JPQL Queries
3434

35-
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`.
35+
JPA's mechanism to return <<projections.dtos,Class-based projections>> using JPQL is *constructor expressions*.
36+
Therefore, your query must define a constructor expression such as `SELECT new com.example.NamesOnly(u.firstname, u.lastname) from User u`.
3637
(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.
37-
As a workaround you may use named queries with `ResultSetMapping` or the Hibernate-specific javadoc:{hibernatejavadocurl}org.hibernate.query.ResultListTransformer[]
38+
As a workaround you may use named queries with `ResultSetMapping` or the Hibernate-specific javadoc:{hibernatejavadocurl}org.hibernate.query.ResultListTransformer[].
39+
40+
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.
3841

3942
===== DTO Projection JPQL Query Rewriting
4043

0 commit comments

Comments
 (0)