Skip to content

Commit 4446026

Browse files
committed
Polishing.
Extend Javadoc, attempt join alias name generation using the initial candidate instead of immediate fallback to generic join_nnn naming. See #3989
1 parent 89797a4 commit 4446026

File tree

4 files changed

+52
-6
lines changed

4 files changed

+52
-6
lines changed

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

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,34 @@ Selection postProcess(Selection selection) {
138138
private static String getAlias(String from, java.util.function.Predicate<String> predicate,
139139
Supplier<String> fallback) {
140140

141-
char c = from.toLowerCase(Locale.ROOT).charAt(0);
142-
String string = Character.toString(c);
143-
if (Character.isJavaIdentifierPart(c) && predicate.test(string)) {
144-
return string;
141+
StringBuilder builder = new StringBuilder();
142+
143+
char[] charArray = from.toLowerCase(Locale.ROOT).toCharArray();
144+
for (char c : charArray) {
145+
146+
if (Character.isJavaIdentifierPart(c)) {
147+
builder.append(c);
148+
} else {
149+
break;
150+
}
151+
}
152+
153+
if (builder.isEmpty()) {
154+
return fallback.get();
155+
}
156+
157+
String identifier = builder.toString();
158+
String firstChar = identifier.substring(0, 1);
159+
160+
if (predicate.test(firstChar)) {
161+
return firstChar;
162+
}
163+
164+
for (int i = 0; i < 10; i++) {
165+
String candidate = firstChar + "_" + i;
166+
if (predicate.test(candidate)) {
167+
return candidate;
168+
}
145169
}
146170

147171
return fallback.get();

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,35 @@
2020
import org.springframework.data.domain.Sort;
2121

2222
/**
23+
* Strategy interface that allows implementations to create JPQL queries providing details about parameter bindings and
24+
* the selection mechanism.
25+
*
2326
* @author Mark Paluch
27+
* @since 4.0
2428
*/
2529
interface JpqlQueryCreator {
2630

31+
/**
32+
* @return whether the query uses a tuple query.
33+
*/
2734
boolean useTupleQuery();
2835

36+
/**
37+
* Create the JPQL query applying {@link Sort}.
38+
*
39+
* @param sort the sort order, can be {@link Sort#unsorted()}.
40+
* @return the rendered JPQL query.
41+
*/
2942
String createQuery(Sort sort);
3043

44+
/*
45+
* @return the parameter bindings.
46+
*/
3147
List<ParameterBinding> getBindings();
3248

49+
/**
50+
* @return parameter binder to use to bind parameters.
51+
*/
3352
ParameterBinder getBinder();
53+
3454
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@ void matchSameEntityMultipleTimesViaDifferentProperties() {
676676
.withParameters(10, "spring") //
677677
.as(QueryCreatorTester::create) //
678678
.expectJpql(
679-
"SELECT o FROM %s o LEFT JOIN o.lineItems l LEFT JOIN l.product p LEFT JOIN l.product2 join_0 WHERE p.name = ?1 AND join_0.name = ?2",
679+
"SELECT o FROM %s o LEFT JOIN o.lineItems l LEFT JOIN l.product p LEFT JOIN l.product2 p_0 WHERE p.name = ?1 AND p_0.name = ?2",
680680
DefaultJpaEntityMetadata.unqualify(Order.class)) //
681681
.validateQuery();
682682
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ void joinOnPaths() {
224224
String fragment = JpqlQueryBuilder.where(productName).eq(literal("ex30"))
225225
.and(JpqlQueryBuilder.where(personName).eq(literal("cstrobl"))).render(ctx(entity));
226226

227-
assertThat(fragment).isEqualTo("p.name = 'ex30' AND join_0.name = 'cstrobl'");
227+
assertThat(fragment).isEqualTo("p.name = 'ex30' AND p_0.name = 'cstrobl'");
228228
}
229229

230230
@Test // GH-3989
@@ -310,8 +310,10 @@ static class LineItem {
310310

311311
@jakarta.persistence.Entity
312312
static class Person {
313+
313314
@Id Long id;
314315
String name;
316+
315317
}
316318

317319
@jakarta.persistence.Entity(name = "my_product")

0 commit comments

Comments
 (0)