diff --git a/spring-data-jpa/src/main/antlr4/org/springframework/data/jpa/repository/query/Hql.g4 b/spring-data-jpa/src/main/antlr4/org/springframework/data/jpa/repository/query/Hql.g4 index 488031b42..731bb16c7 100644 --- a/spring-data-jpa/src/main/antlr4/org/springframework/data/jpa/repository/query/Hql.g4 +++ b/spring-data-jpa/src/main/antlr4/org/springframework/data/jpa/repository/query/Hql.g4 @@ -579,7 +579,7 @@ dealingWithNullExpression // https://docs.jboss.org/hibernate/orm/6.1/userguide/html_single/Hibernate_User_Guide.html#hql-like-predicate stringPatternMatching - : expression NOT? (LIKE | ILIKE) expression (ESCAPE character)? + : expression NOT? (LIKE | ILIKE) expression (ESCAPE expression)? ; // https://docs.jboss.org/hibernate/orm/6.1/userguide/html_single/Hibernate_User_Guide.html#hql-elements-indices diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/HqlQueryRenderer.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/HqlQueryRenderer.java index 39d6271fe..5446173ca 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/HqlQueryRenderer.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/HqlQueryRenderer.java @@ -2124,7 +2124,7 @@ class HqlQueryRenderer extends HqlBaseVisitor> { if (ctx.ESCAPE() != null) { tokens.add(new JpaQueryParsingToken(ctx.ESCAPE())); - tokens.addAll(visit(ctx.character())); + tokens.addAll(visit(ctx.expression(2))); } return tokens; diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryRenderer.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryRenderer.java index 0a148f145..b5a41fe99 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryRenderer.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryRenderer.java @@ -1206,6 +1206,12 @@ class JpqlQueryRenderer extends JpqlBaseVisitor> { tokens.add(new JpaQueryParsingToken(ctx.LIKE())); tokens.addAll(visit(ctx.pattern_value())); + if (ctx.ESCAPE() != null) { + + tokens.add(new JpaQueryParsingToken(ctx.ESCAPE())); + tokens.addAll(visit(ctx.escape_character())); + } + return tokens; } diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/EclipseLinkUserRepositoryFinderTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/EclipseLinkUserRepositoryFinderTests.java index 0caf735d4..1b6bc2a7b 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/EclipseLinkUserRepositoryFinderTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/EclipseLinkUserRepositoryFinderTests.java @@ -34,4 +34,22 @@ class EclipseLinkUserRepositoryFinderTests extends UserRepositoryFinderTests { @Disabled @Override void executesInKeywordForPageCorrectly() {} + + @Disabled("Can't get ESCAPE clause working with EclipseLink. See #2955") + @Override + void escapingInLikeSpels() { + super.escapingInLikeSpels(); + } + + @Disabled("Can't get ESCAPE clause working with EclipseLink. See #2955") + @Override + void escapingInLikeSpelsInThePresenceOfEscapeCharacters() { + super.escapingInLikeSpelsInThePresenceOfEscapeCharacters(); + } + + @Disabled("Can't get ESCAPE clause working with EclipseLink. See #2955") + @Override + void escapingInLikeSpelsInThePresenceOfEscapedWildcards() { + super.escapingInLikeSpelsInThePresenceOfEscapedWildcards(); + } } diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java index 6fa3e2b00..bccc417ea 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java @@ -25,7 +25,6 @@ import java.util.List; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -235,7 +234,6 @@ class UserRepositoryFinderTests { .isEmpty(); } - @Disabled("Can't get ESCAPE clause working with Hibernate") @Test // DATAJPA-1519 void escapingInLikeSpels() { @@ -246,7 +244,6 @@ class UserRepositoryFinderTests { assertThat(userRepository.findContainingEscaped("att_")).containsExactly(extra); } - @Disabled("Can't get ESCAPE clause working with Hibernate") @Test // DATAJPA-1522 void escapingInLikeSpelsInThePresenceOfEscapeCharacters() { @@ -256,7 +253,6 @@ class UserRepositoryFinderTests { assertThat(userRepository.findContainingEscaped("att\\x")).containsExactly(withEscapeCharacter); } - @Disabled("Can't get ESCAPE clause working with Hibernate") @Test // DATAJPA-1522 void escapingInLikeSpelsInThePresenceOfEscapedWildcards() { @@ -288,8 +284,7 @@ class UserRepositoryFinderTests { List rolesAndFirstnameBy = userRepository.findRolesAndFirstnameBy(); - assertThat(rolesAndFirstnameBy) - .isNotNull(); + assertThat(rolesAndFirstnameBy).isNotNull(); for (RolesAndFirstname rolesAndFirstname : rolesAndFirstnameBy) { assertThat(rolesAndFirstname.getFirstname()).isNotNull(); diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java index 5eb749039..821b119a7 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java @@ -625,7 +625,7 @@ public interface UserRepository extends JpaRepository, JpaSpecifi List findByNamedQueryWithConstructorExpression(); // DATAJPA-1519 - @Query("select u from User u where u.lastname like '%?#{escape([0])}%' escape ?#{escapeCharacter()}") + @Query("select u from User u where u.lastname like %?#{escape([0])}% escape ?#{escapeCharacter()}") List findContainingEscaped(String namePart); // DATAJPA-1303