Skip to content

Commit 49ebc1a

Browse files
committed
Sort properties shouldn't overlap with aliases.
When using an alias in a query, verify using "." as a proper separator against both alias projections as the primary alias to ensure that a Sort property doesn't overlap with an alias. See #3054
1 parent f8a0476 commit 49ebc1a

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,18 @@ private boolean shouldPrefixWithAlias(Sort.Order order, String primaryFromAlias)
131131
return false;
132132
}
133133

134+
// If the Sort starts with the primary alias
135+
if (order.getProperty().startsWith(primaryFromAlias + ".")) {
136+
return false;
137+
}
138+
134139
// If the Sort references an alias directly
135140
if (projectionAliases.contains(order.getProperty())) {
136141
return false;
137142
}
138143

139144
// If the Sort property starts with an alias
140-
if (projectionAliases.stream().anyMatch(alias -> order.getProperty().startsWith(alias))) {
145+
if (projectionAliases.stream().anyMatch(alias -> order.getProperty().startsWith(alias + "."))) {
141146
return false;
142147
}
143148

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

+25
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,31 @@ void sortingRecognizesJoinAliases() {
10061006
""");
10071007
}
10081008

1009+
@Test // GH-3054
1010+
void aliasesShouldNotOverlapWithSortProperties() {
1011+
1012+
assertThat(
1013+
createQueryFor("select e from Employee e where e.name = :name", Sort.by(Sort.Order.desc("evaluationDate"))))
1014+
.isEqualToIgnoringWhitespace(
1015+
"select e from Employee e where e.name = :name order by e.evaluationDate desc");
1016+
1017+
assertThat(createQueryFor("select e from Employee e join training t where e.name = :name",
1018+
Sort.by(Sort.Order.desc("trainingDueDate")))).isEqualToIgnoringWhitespace(
1019+
"select e from Employee e join training t where e.name = :name order by e.trainingDueDate desc");
1020+
1021+
assertThat(createQueryFor("select e from Employee e join training t where e.name = :name",
1022+
Sort.by(Sort.Order.desc("t.trainingDueDate")))).isEqualToIgnoringWhitespace(
1023+
"select e from Employee e join training t where e.name = :name order by t.trainingDueDate desc");
1024+
1025+
assertThat(createQueryFor("SELECT t3 FROM Test3 t3 JOIN t3.test2 t2 JOIN t2.test1 test WHERE test.id = :test1Id",
1026+
Sort.by(Sort.Order.desc("testDuplicateColumnName")))).isEqualToIgnoringWhitespace(
1027+
"SELECT t3 FROM Test3 t3 JOIN t3.test2 t2 JOIN t2.test1 test WHERE test.id = :test1Id order by t3.testDuplicateColumnName desc");
1028+
1029+
assertThat(createQueryFor("SELECT t3 FROM Test3 t3 JOIN t3.test2 x WHERE x.id = :test2Id",
1030+
Sort.by(Sort.Order.desc("t3.testDuplicateColumnName")))).isEqualToIgnoringWhitespace(
1031+
"SELECT t3 FROM Test3 t3 JOIN t3.test2 x WHERE x.id = :test2Id order by t3.testDuplicateColumnName desc");
1032+
}
1033+
10091034
private void assertCountQuery(String originalQuery, String countQuery) {
10101035
assertThat(createCountQueryFor(originalQuery)).isEqualTo(countQuery);
10111036
}

0 commit comments

Comments
 (0)