Skip to content

Commit 38ced42

Browse files
gregturnmp911de
authored andcommitted
Resolve handling of ESCAPE clause with LIKE queries on Hibernate.
The HQL parser has to handle parameters in addition to character values in order to support SpEL. Closes #2954 Original Pull Request: #2956.
1 parent e0cfe41 commit 38ced42

File tree

6 files changed

+28
-9
lines changed

6 files changed

+28
-9
lines changed

spring-data-jpa/src/main/antlr4/org/springframework/data/jpa/repository/query/Hql.g4

+1-1
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ dealingWithNullExpression
579579

580580
// https://docs.jboss.org/hibernate/orm/6.1/userguide/html_single/Hibernate_User_Guide.html#hql-like-predicate
581581
stringPatternMatching
582-
: expression NOT? (LIKE | ILIKE) expression (ESCAPE character)?
582+
: expression NOT? (LIKE | ILIKE) expression (ESCAPE expression)?
583583
;
584584

585585
// https://docs.jboss.org/hibernate/orm/6.1/userguide/html_single/Hibernate_User_Guide.html#hql-elements-indices

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -2124,7 +2124,7 @@ public List<JpaQueryParsingToken> visitStringPatternMatching(HqlParser.StringPat
21242124
if (ctx.ESCAPE() != null) {
21252125

21262126
tokens.add(new JpaQueryParsingToken(ctx.ESCAPE()));
2127-
tokens.addAll(visit(ctx.character()));
2127+
tokens.addAll(visit(ctx.expression(2)));
21282128
}
21292129

21302130
return tokens;

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

+6
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,12 @@ public List<JpaQueryParsingToken> visitLike_expression(JpqlParser.Like_expressio
12061206
tokens.add(new JpaQueryParsingToken(ctx.LIKE()));
12071207
tokens.addAll(visit(ctx.pattern_value()));
12081208

1209+
if (ctx.ESCAPE() != null) {
1210+
1211+
tokens.add(new JpaQueryParsingToken(ctx.ESCAPE()));
1212+
tokens.addAll(visit(ctx.escape_character()));
1213+
}
1214+
12091215
return tokens;
12101216
}
12111217

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

+18
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,22 @@ void executesNotInQueryCorrectly() {}
3434
@Disabled
3535
@Override
3636
void executesInKeywordForPageCorrectly() {}
37+
38+
@Disabled("Can't get ESCAPE clause working with EclipseLink. See #2955")
39+
@Override
40+
void escapingInLikeSpels() {
41+
super.escapingInLikeSpels();
42+
}
43+
44+
@Disabled("Can't get ESCAPE clause working with EclipseLink. See #2955")
45+
@Override
46+
void escapingInLikeSpelsInThePresenceOfEscapeCharacters() {
47+
super.escapingInLikeSpelsInThePresenceOfEscapeCharacters();
48+
}
49+
50+
@Disabled("Can't get ESCAPE clause working with EclipseLink. See #2955")
51+
@Override
52+
void escapingInLikeSpelsInThePresenceOfEscapedWildcards() {
53+
super.escapingInLikeSpelsInThePresenceOfEscapedWildcards();
54+
}
3755
}

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

+1-6
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
import org.junit.jupiter.api.AfterEach;
2727
import org.junit.jupiter.api.BeforeEach;
28-
import org.junit.jupiter.api.Disabled;
2928
import org.junit.jupiter.api.Test;
3029
import org.junit.jupiter.api.extension.ExtendWith;
3130
import org.springframework.beans.factory.annotation.Autowired;
@@ -235,7 +234,6 @@ void parametersForContainsGetProperlyEscaped() {
235234
.isEmpty();
236235
}
237236

238-
@Disabled("Can't get ESCAPE clause working with Hibernate")
239237
@Test // DATAJPA-1519
240238
void escapingInLikeSpels() {
241239

@@ -246,7 +244,6 @@ void escapingInLikeSpels() {
246244
assertThat(userRepository.findContainingEscaped("att_")).containsExactly(extra);
247245
}
248246

249-
@Disabled("Can't get ESCAPE clause working with Hibernate")
250247
@Test // DATAJPA-1522
251248
void escapingInLikeSpelsInThePresenceOfEscapeCharacters() {
252249

@@ -256,7 +253,6 @@ void escapingInLikeSpelsInThePresenceOfEscapeCharacters() {
256253
assertThat(userRepository.findContainingEscaped("att\\x")).containsExactly(withEscapeCharacter);
257254
}
258255

259-
@Disabled("Can't get ESCAPE clause working with Hibernate")
260256
@Test // DATAJPA-1522
261257
void escapingInLikeSpelsInThePresenceOfEscapedWildcards() {
262258

@@ -288,8 +284,7 @@ void executesQueryWithProjectionContainingReferenceToPluralAttribute() {
288284

289285
List<RolesAndFirstname> rolesAndFirstnameBy = userRepository.findRolesAndFirstnameBy();
290286

291-
assertThat(rolesAndFirstnameBy)
292-
.isNotNull();
287+
assertThat(rolesAndFirstnameBy).isNotNull();
293288

294289
for (RolesAndFirstname rolesAndFirstname : rolesAndFirstnameBy) {
295290
assertThat(rolesAndFirstname.getFirstname()).isNotNull();

spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ List<User> findUsersByFirstnameForSpELExpressionWithParameterIndexOnlyWithEntity
625625
List<NameOnlyDto> findByNamedQueryWithConstructorExpression();
626626

627627
// DATAJPA-1519
628-
@Query("select u from User u where u.lastname like '%?#{escape([0])}%' escape ?#{escapeCharacter()}")
628+
@Query("select u from User u where u.lastname like %?#{escape([0])}% escape ?#{escapeCharacter()}")
629629
List<User> findContainingEscaped(String namePart);
630630

631631
// DATAJPA-1303

0 commit comments

Comments
 (0)