Skip to content

Commit 51a8885

Browse files
committed
DATAJPA-726 - Fixed alias detection for queries containing joins.
We now not only detect alias in left (outer) joins but basically all of them to find out whether or not to prefix sort expressions with the root alias.
1 parent a28e98e commit 51a8885

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2008-2014 the original author or authors.
2+
* Copyright 2008-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -84,14 +84,17 @@ public abstract class QueryUtils {
8484
private static final String IDENTIFIER = "[\\p{Alnum}._$]+";
8585
private static final String IDENTIFIER_GROUP = String.format("(%s)", IDENTIFIER);
8686

87-
private static final String LEFT_JOIN = "left (outer )?join " + IDENTIFIER + " (as )?" + IDENTIFIER_GROUP;
88-
private static final Pattern LEFT_JOIN_PATTERN = Pattern.compile(LEFT_JOIN, Pattern.CASE_INSENSITIVE);
87+
private static final String JOIN = "join " + IDENTIFIER + " (as )?" + IDENTIFIER_GROUP;
88+
private static final Pattern JOIN_PATTERN = Pattern.compile(JOIN, Pattern.CASE_INSENSITIVE);
8989

9090
private static final String EQUALS_CONDITION_STRING = "%s.%s = :%s";
9191
private static final Pattern ORDER_BY = Pattern.compile(".*order\\s+by\\s+.*", CASE_INSENSITIVE);
9292

9393
private static final Map<PersistentAttributeType, Class<? extends Annotation>> ASSOCIATION_TYPES;
9494

95+
private static final int QUERY_JOIN_ALIAS_GROUP_INDEX = 2;
96+
private static final int VARIABLE_NAME_GROUP_INDEX = 4;
97+
9598
static {
9699

97100
StringBuilder builder = new StringBuilder();
@@ -250,11 +253,11 @@ private static String getOrderClause(Set<String> joinAliases, String alias, Orde
250253
static Set<String> getOuterJoinAliases(String query) {
251254

252255
Set<String> result = new HashSet<String>();
253-
Matcher matcher = LEFT_JOIN_PATTERN.matcher(query);
256+
Matcher matcher = JOIN_PATTERN.matcher(query);
254257

255258
while (matcher.find()) {
256259

257-
String alias = matcher.group(3);
260+
String alias = matcher.group(QUERY_JOIN_ALIAS_GROUP_INDEX);
258261
if (StringUtils.hasText(alias)) {
259262
result.add(alias);
260263
}
@@ -358,7 +361,7 @@ public static String createCountQueryFor(String originalQuery, String countProje
358361

359362
if (countProjection == null) {
360363

361-
String variable = matcher.matches() ? matcher.group(4) : null;
364+
String variable = matcher.matches() ? matcher.group(VARIABLE_NAME_GROUP_INDEX) : null;
362365
boolean useVariable = variable != null && StringUtils.hasText(variable) && !variable.startsWith("new")
363366
&& !variable.startsWith("count(") && !variable.contains(",");
364367

src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsUnitTests.java

+17-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2008-2014 the original author or authors.
2+
* Copyright 2008-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -150,11 +150,13 @@ public void detectsJoinAliasesCorrectly() {
150150
assertThat(aliases, hasSize(1));
151151
assertThat(aliases, hasItems("b2_$ar"));
152152

153-
aliases = getOuterJoinAliases("select p from Person p left outer join x.foo as b2_$ar, left join x.bar as foo where …");
153+
aliases = getOuterJoinAliases(
154+
"select p from Person p left outer join x.foo as b2_$ar, left join x.bar as foo where …");
154155
assertThat(aliases, hasSize(2));
155156
assertThat(aliases, hasItems("b2_$ar", "foo"));
156157

157-
aliases = getOuterJoinAliases("select p from Person p left join x.foo as b2_$ar, left outer join x.bar foo where …");
158+
aliases = getOuterJoinAliases(
159+
"select p from Person p left join x.foo as b2_$ar, left outer join x.bar foo where …");
158160
assertThat(aliases, hasSize(2));
159161
assertThat(aliases, hasItems("b2_$ar", "foo"));
160162
}
@@ -281,6 +283,18 @@ public void createCountQueryFromTheGivenCountProjection() {
281283
is("select count(p.lastname) from Person p"));
282284
}
283285

286+
/**
287+
* @see DATAJPA-726
288+
*/
289+
@Test
290+
public void detectsAliassesInPlainJoins() {
291+
292+
String query = "select p from Customer c join c.productOrder p where p.delayed = true";
293+
Sort sort = new Sort("p.lineItems");
294+
295+
assertThat(applySorting(query, sort, "c"), endsWith("order by p.lineItems asc"));
296+
}
297+
284298
private void assertCountQuery(String originalQuery, String countQuery) {
285299
assertThat(createCountQueryFor(originalQuery), is(countQuery));
286300
}

0 commit comments

Comments
 (0)