Skip to content

Commit 0168ba3

Browse files
author
heehoonhong
committed
Refine DTO projection rewrite for JPA 4.0 implicit mapping
1 parent c15c913 commit 0168ba3

2 files changed

Lines changed: 18 additions & 5 deletions

File tree

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,20 @@ public boolean applyRewriting() {
5555
}
5656

5757
public boolean canRewrite() {
58-
return !selectItems.isEmpty() && applyRewriting();
58+
59+
if (selectItems.isEmpty() || !applyRewriting()) {
60+
return false;
61+
}
62+
63+
// Avoid rewriting if the selection list is already expanded and the target type is a record
64+
// to leverage JPA 4.0 implicit DTO mapping.
65+
boolean expansion = selectItems.size() == 1 && selectItems.get(0).size() == 1;
66+
67+
if (!expansion && returnedType.getReturnedType().isRecord()) {
68+
return false;
69+
}
70+
71+
return true;
5972
}
6073

6174
public void appendSelectItem(QueryTokenStream selectItem) {

spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/AbstractDtoQueryTransformerUnitTests.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ void shouldRewriteSelectionToConstructorExpression() {
5656
QueryTokenStream visit = getTransformer(parser).visit(parser.getContext());
5757

5858
assertThat(QueryRenderer.TokenRenderer.render(visit)).isEqualTo(
59-
"SELECT new org.springframework.data.jpa.repository.query.AbstractDtoQueryTransformerUnitTests$MyRecord(p.name) from Person p");
59+
"SELECT p.name from Person p");
6060
}
6161

6262
@Test // GH-3076
@@ -99,7 +99,7 @@ void shouldTranslatePropertySelectionToDto() {
9999
QueryTokenStream visit = getTransformer(parser).visit(parser.getContext());
100100

101101
assertThat(QueryRenderer.TokenRenderer.render(visit)).isEqualTo(
102-
"SELECT new org.springframework.data.jpa.repository.query.AbstractDtoQueryTransformerUnitTests$MyRecord(p.foo, p.bar, sum(p.age)) from Person p");
102+
"SELECT p.foo, p.bar, sum(p.age) from Person p");
103103
}
104104

105105
@Test // GH-3895
@@ -110,7 +110,7 @@ void shouldStripAliasesFromDtoProjection() {
110110
QueryTokenStream visit = getTransformer(parser).visit(parser.getContext());
111111

112112
assertThat(QueryRenderer.TokenRenderer.render(visit)).isEqualTo(
113-
"SELECT new org.springframework.data.jpa.repository.query.AbstractDtoQueryTransformerUnitTests$MyRecord(sum(p.age), p.foo, p.bar) from Person p");
113+
"SELECT sum(p.age) As age, p.foo as foo, p.bar AS bar from Person p");
114114
}
115115

116116
@Test // GH-3895
@@ -122,7 +122,7 @@ void shouldStripAliasesFromDtoProjectionWithSubquery() {
122122
QueryTokenStream visit = getTransformer(parser).visit(parser.getContext());
123123

124124
assertThat(QueryRenderer.TokenRenderer.render(visit)).isEqualTo(
125-
"SELECT new org.springframework.data.jpa.repository.query.AbstractDtoQueryTransformerUnitTests$MyRecord(p.foo, p.bar, cast(p.age as INTEGER), (SELECT b.foo FROM Bar AS b)) from Person p");
125+
"SELECT p.foo as foo, p.bar AS bar, cast(p.age as INTEGER) As age, (SELECT b.foo FROM Bar AS b) from Person p");
126126
}
127127

128128
private JpaQueryMethod getMethod(String name, Class<?>... parameterTypes) {

0 commit comments

Comments
 (0)