Skip to content

Commit 25a7c10

Browse files
author
oualid.bouh
committed
GH-4135: Projection Collision
1 parent df091b9 commit 25a7c10

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
* @author Greg Turnquist
7070
* @author Christoph Strobl
7171
* @author Jinmyeong Kim
72+
* @author Oualid Bouh
7273
*/
7374
public class JpaQueryCreator extends AbstractQueryCreator<String, JpqlQueryBuilder.Predicate>
7475
implements JpqlQueryCreator {
@@ -299,7 +300,7 @@ private JpqlQueryBuilder.Select doSelect(Sort sort) {
299300
List<JpqlQueryBuilder.Expression> paths = new ArrayList<>(requiredSelection.size());
300301
for (String selection : requiredSelection) {
301302
paths.add(JpqlUtils.toExpressionRecursively(metamodel, entity, entityType,
302-
PropertyPath.from(selection, returnedType.getDomainType()), true));
303+
PropertyPath.from(selection, returnedType.getDomainType()), true).as(selection));
303304
}
304305

305306
JpqlQueryBuilder.Expression distance = null;

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
*
6666
* @author Christoph Strobl
6767
* @author Mark Paluch
68+
* @author Oualid Bouh
6869
*/
6970
class JpaQueryCreatorTests {
7071

@@ -76,6 +77,9 @@ class JpaQueryCreatorTests {
7677

7778
static List<JpqlQueryTemplates> ignoreCaseTemplates = List.of(JpqlQueryTemplates.LOWER, JpqlQueryTemplates.UPPER);
7879

80+
private static final TestMetaModel ORDER_WITH_RELATIONS = TestMetaModel.hibernateModel(
81+
OrderWithRelations.class, Customer.class, Supplier.class);
82+
7983
@Test // GH-3588
8084
void simpleProperty() {
8185

@@ -1131,4 +1135,45 @@ JpaQueryCreator initJpaQueryCreator() {
11311135
return queryCreator(partTree, returnedType, metamodel, queryTemplates, parameterAccessor.get());
11321136
}
11331137
}
1138+
1139+
@Test // GH-4135
1140+
void interfaceProjectionWithMultipleJoinsShouldGenerateUniqueAliases() {
1141+
1142+
queryCreator(ORDER_WITH_RELATIONS)
1143+
.forTree(OrderWithRelations.class, "findProjectionById")
1144+
.returning(OrderSummaryProjection.class)
1145+
.withParameters(1L)
1146+
.as(QueryCreatorTester::create)
1147+
.expectJpql(
1148+
"SELECT o.id id, c.id customerId, s.id supplierId, c.name customerName, s.name supplierName FROM %s o LEFT JOIN o.customer c LEFT JOIN o.supplier s WHERE o.id = ?1",
1149+
DefaultJpaEntityMetadata.unqualify(OrderWithRelations.class))
1150+
.validateQuery();
1151+
}
1152+
1153+
@jakarta.persistence.Entity
1154+
static class OrderWithRelations {
1155+
@Id Long id;
1156+
@ManyToOne Customer customer;
1157+
@ManyToOne Supplier supplier;
1158+
}
1159+
1160+
@jakarta.persistence.Entity
1161+
static class Customer {
1162+
@Id Long id;
1163+
String name;
1164+
}
1165+
1166+
@jakarta.persistence.Entity
1167+
static class Supplier {
1168+
@Id Long id;
1169+
String name;
1170+
}
1171+
1172+
interface OrderSummaryProjection {
1173+
Long getId();
1174+
Long getCustomerId(); // → customer.id
1175+
Long getSupplierId(); // → supplier.id
1176+
String getCustomerName(); // → customer.name
1177+
String getSupplierName(); // → supplier.name
1178+
}
11341179
}

0 commit comments

Comments
 (0)