From e2e5af80926f84942b8b6965bdc3132774e7b022 Mon Sep 17 00:00:00 2001 From: Martin Fekete Date: Tue, 12 Aug 2025 13:44:23 +0200 Subject: [PATCH 1/4] allow to customize json search function --- .../rsql/jsonb/JsonbExpressionBuilder.java | 4 --- .../perplexhub/rsql/jsonb/JsonbSupport.java | 28 +++++++++------ .../jsonb/JsonbExpressionBuilderTest.java | 35 ++++++++++++++++++- 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilder.java b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilder.java index 5d946820..ee2b17c0 100644 --- a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilder.java +++ b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilder.java @@ -161,10 +161,6 @@ public ArgValue convert(String s) { Map.entry(BETWEEN, "(%1$s >= %2$s && %1$s <= %3$s)") ); - private static final String JSONB_PATH_EXISTS = "jsonb_path_exists"; - - private static final String JSONB_PATH_EXISTS_TZ = "jsonb_path_exists_tz"; - private final ComparisonOperator operator; private final String keyPath; private final List values; diff --git a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbSupport.java b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbSupport.java index 4c0e7be3..7d5ce5b2 100644 --- a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbSupport.java +++ b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbSupport.java @@ -1,14 +1,6 @@ package io.github.perplexhub.rsql.jsonb; -import static io.github.perplexhub.rsql.RSQLVisitorBase.getEntityManagerMap; - -import java.lang.reflect.Field; -import java.util.EnumSet; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - import cz.jirutka.rsql.parser.ast.ComparisonNode; import cz.jirutka.rsql.parser.ast.ComparisonOperator; import io.github.perplexhub.rsql.RSQLOperators; @@ -16,13 +8,19 @@ import io.github.perplexhub.rsql.ResolvedExpression; import jakarta.persistence.Column; import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.Expression; import jakarta.persistence.criteria.Path; -import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.Attribute; import jakarta.persistence.metamodel.ManagedType; import org.springframework.orm.jpa.vendor.Database; +import java.lang.reflect.Field; +import java.util.EnumSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import static io.github.perplexhub.rsql.RSQLVisitorBase.getEntityManagerMap; + /** * Support for jsonb expression. */ @@ -30,6 +28,16 @@ public class JsonbSupport { public static boolean DATE_TIME_SUPPORT = false; + /** + * Postgresql {@code jsonb_path_exists} function to use + */ + public static String JSONB_PATH_EXISTS = "jsonb_path_exists"; + + /** + * Postgresql {@code jsonb_path_exists_tz} function to use + */ + public static String JSONB_PATH_EXISTS_TZ = "jsonb_path_exists_tz"; + private static final Set JSON_SUPPORT = EnumSet.of(Database.POSTGRESQL); private static final Map NEGATE_OPERATORS = diff --git a/rsql-jpa/src/test/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilderTest.java b/rsql-jpa/src/test/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilderTest.java index c97d7d34..462cd731 100644 --- a/rsql-jpa/src/test/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilderTest.java +++ b/rsql-jpa/src/test/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilderTest.java @@ -12,7 +12,8 @@ import java.util.Objects; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.params.provider.Arguments.arguments; class JsonbExpressionBuilderTest { @@ -37,6 +38,27 @@ void testJsonbPathExpressionWithTemporal(ComparisonOperator operator, String key assertEquals(expectedJsonbPath, expression.jsonbPath()); } + @ParameterizedTest + @MethodSource("customized") + void testJsonbPathExpressionCustomized(ComparisonOperator operator, String keyPath, List arguments, String expectedJsonbFunction, String expectedJsonbPath) { + String jsonbPathExists = JsonbSupport.JSONB_PATH_EXISTS; + String jsonbPathExistsTz = JsonbSupport.JSONB_PATH_EXISTS_TZ; + try { + JsonbSupport.JSONB_PATH_EXISTS = "my_jsonb_path_exists"; + JsonbSupport.JSONB_PATH_EXISTS_TZ = "my_jsonb_path_exists_tz"; + JsonbSupport.DATE_TIME_SUPPORT = true; + JsonbExpressionBuilder builder = new JsonbExpressionBuilder(operator, keyPath, arguments); + var expression = builder.getJsonPathExpression(); + assertEquals(expectedJsonbFunction, expression.jsonbFunction()); + assertEquals(expectedJsonbPath, expression.jsonbPath()); + } catch (Exception e) { + throw e; + } finally { + JsonbSupport.JSONB_PATH_EXISTS = jsonbPathExists; + JsonbSupport.JSONB_PATH_EXISTS_TZ = jsonbPathExistsTz; + } + } + static Stream data() { return Stream.of( allOperators(), @@ -78,6 +100,17 @@ static Stream conversion() { ).filter(Objects::nonNull); } + static Stream customized() { + + return Stream.of( + arguments(RSQLOperators.EQUAL, "json.equal_key", Collections.singletonList("value"), "my_jsonb_path_exists", "$.equal_key ? (@ == \"value\")"), + arguments(RSQLOperators.GREATER_THAN, "json.greater_than_key", Collections.singletonList("value"), "my_jsonb_path_exists", "$.greater_than_key ? (@ > \"value\")"), + arguments(RSQLOperators.EQUAL, "json.equal_key", Collections.singletonList("1970-01-01T00:00:00.000"), "my_jsonb_path_exists", "$.equal_key ? (@.datetime() == \"1970-01-01T00:00:00.000\".datetime())"), + arguments(RSQLOperators.EQUAL, "json.equal_key", Collections.singletonList("1970-01-01T00:00:00.000Z"), "my_jsonb_path_exists_tz", "$.equal_key ? (@.datetime() == \"1970-01-01T00:00:00.000Z\".datetime())"), + null + ).filter(Objects::nonNull); + } + static Stream temporal() { return Stream.of( From 79601648369fd36e74f2bfae776e9b331d0d0525 Mon Sep 17 00:00:00 2001 From: Martin Fekete Date: Tue, 12 Aug 2025 14:06:08 +0200 Subject: [PATCH 2/4] undo imports changes --- .../perplexhub/rsql/jsonb/JsonbSupport.java | 18 ++++++++++-------- .../rsql/jsonb/JsonbExpressionBuilderTest.java | 3 +-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbSupport.java b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbSupport.java index 7d5ce5b2..4372ce13 100644 --- a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbSupport.java +++ b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbSupport.java @@ -1,6 +1,14 @@ package io.github.perplexhub.rsql.jsonb; +import static io.github.perplexhub.rsql.RSQLVisitorBase.getEntityManagerMap; + +import java.lang.reflect.Field; +import java.util.EnumSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + import cz.jirutka.rsql.parser.ast.ComparisonNode; import cz.jirutka.rsql.parser.ast.ComparisonOperator; import io.github.perplexhub.rsql.RSQLOperators; @@ -8,19 +16,13 @@ import io.github.perplexhub.rsql.ResolvedExpression; import jakarta.persistence.Column; import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.Expression; import jakarta.persistence.criteria.Path; +import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.Attribute; import jakarta.persistence.metamodel.ManagedType; import org.springframework.orm.jpa.vendor.Database; -import java.lang.reflect.Field; -import java.util.EnumSet; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -import static io.github.perplexhub.rsql.RSQLVisitorBase.getEntityManagerMap; - /** * Support for jsonb expression. */ diff --git a/rsql-jpa/src/test/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilderTest.java b/rsql-jpa/src/test/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilderTest.java index 462cd731..28965ab3 100644 --- a/rsql-jpa/src/test/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilderTest.java +++ b/rsql-jpa/src/test/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilderTest.java @@ -12,8 +12,7 @@ import java.util.Objects; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.params.provider.Arguments.arguments; class JsonbExpressionBuilderTest { From ca63c3fbd2ae80578211b0fb70ec266791c48216 Mon Sep 17 00:00:00 2001 From: Martin Fekete Date: Tue, 19 Aug 2025 18:34:57 +0200 Subject: [PATCH 3/4] move json query functions configuration to QuerySupport --- .../github/perplexhub/rsql/QuerySupport.java | 8 ++++++ .../rsql/RSQLJPAPredicateConverter.java | 21 +++++++++++++-- .../perplexhub/rsql/RSQLJPASupport.java | 3 ++- .../rsql/jsonb/JsonbExpressionBuilder.java | 15 ++++++++++- .../perplexhub/rsql/jsonb/JsonbSupport.java | 16 ++---------- .../rsql/RSQLJPASupportPostgresJsonTest.java | 26 ++++++++++++++++--- .../jsonb/JsonbExpressionBuilderTest.java | 21 ++++----------- 7 files changed, 73 insertions(+), 37 deletions(-) diff --git a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/QuerySupport.java b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/QuerySupport.java index bd8cb261..7fffe5d5 100644 --- a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/QuerySupport.java +++ b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/QuerySupport.java @@ -27,6 +27,14 @@ public class QuerySupport { private Map, List> propertyBlacklist; private Collection procedureWhiteList; private Collection procedureBlackList; + /** + * Postgresql {@code jsonb_path_exists} function to use + */ + private String jsonbPathExists; + /** + * Postgresql {@code jsonb_path_exists_tz} function to use + */ + private String jsonbPathExistsTz; public static class QuerySupportBuilder {} diff --git a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/RSQLJPAPredicateConverter.java b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/RSQLJPAPredicateConverter.java index 9dcb9211..bbd8d156 100644 --- a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/RSQLJPAPredicateConverter.java +++ b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/RSQLJPAPredicateConverter.java @@ -37,6 +37,8 @@ public class RSQLJPAPredicateConverter extends RSQLVisitorBase private final Collection procedureBlackList; private final boolean strictEquality; private final Character likeEscapeCharacter; + private final String jsonbPathExists; + private final String jsonbPathExistsTz; public RSQLJPAPredicateConverter(CriteriaBuilder builder, Map propertyPathMapper) { this(builder, propertyPathMapper, null, null); @@ -54,6 +56,17 @@ public RSQLJPAPredicateConverter(CriteriaBuilder builder, Map pr this(builder, propertyPathMapper, customPredicates, joinHints, procedureWhiteList, procedureBlackList, false, null); } + public RSQLJPAPredicateConverter(CriteriaBuilder builder, + Map propertyPathMapper, + List> customPredicates, + Map joinHints, + Collection proceduresWhiteList, + Collection proceduresBlackList, + boolean strictEquality, + Character likeEscapeCharacter) { + this(builder, propertyPathMapper, customPredicates, joinHints, proceduresWhiteList, proceduresBlackList, strictEquality, likeEscapeCharacter, null, null); + } + public RSQLJPAPredicateConverter(CriteriaBuilder builder, Map propertyPathMapper, List> customPredicates, @@ -61,7 +74,9 @@ public RSQLJPAPredicateConverter(CriteriaBuilder builder, Collection proceduresWhiteList, Collection proceduresBlackList, boolean strictEquality, - Character likeEscapeCharacter) { + Character likeEscapeCharacter, + String jsonbPathExists, + String jsonbPathExistsTz) { this.builder = builder; this.propertyPathMapper = propertyPathMapper != null ? propertyPathMapper : Collections.emptyMap(); this.customPredicates = customPredicates != null ? customPredicates.stream().collect(Collectors.toMap(RSQLCustomPredicate::getOperator, Function.identity(), (a, b) -> a)) : Collections.emptyMap(); @@ -70,6 +85,8 @@ public RSQLJPAPredicateConverter(CriteriaBuilder builder, this.procedureBlackList = proceduresBlackList != null ? proceduresBlackList : Collections.emptyList(); this.strictEquality = strictEquality; this.likeEscapeCharacter = likeEscapeCharacter; + this.jsonbPathExists = jsonbPathExists; + this.jsonbPathExistsTz = jsonbPathExistsTz; } RSQLJPAContext findPropertyPath(String propertyPath, Path startRoot) { @@ -244,7 +261,7 @@ private ResolvedExpression resolveExpression(ComparisonNode node, From root, Sel String jsonbPath = JsonbSupport.jsonPathOfSelector(attribute, jsonSelector); if(jsonbPath.contains(".")) { ComparisonNode jsonbNode = node.withSelector(jsonbPath); - return JsonbSupport.jsonbPathExistsExpression(builder, jsonbNode, path); + return JsonbSupport.jsonbPathExistsExpression(builder, jsonbNode, path, jsonbPathExists, jsonbPathExistsTz); } else { final Expression expression; if (path instanceof JpaExpression jpaExpression) { diff --git a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/RSQLJPASupport.java b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/RSQLJPASupport.java index c9400c32..3ac4a1e5 100644 --- a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/RSQLJPASupport.java +++ b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/RSQLJPASupport.java @@ -127,7 +127,8 @@ public static Specification toSpecification(final QuerySupport querySuppo RSQLJPAPredicateConverter visitor = new RSQLJPAPredicateConverter(cb, querySupport.getPropertyPathMapper(), querySupport.getCustomPredicates(), querySupport.getJoinHints(), querySupport.getProcedureWhiteList(), querySupport.getProcedureBlackList(), - querySupport.isStrictEquality(), querySupport.getLikeEscapeCharacter()); + querySupport.isStrictEquality(), querySupport.getLikeEscapeCharacter(), + querySupport.getJsonbPathExists(), querySupport.getJsonbPathExistsTz()); visitor.setPropertyWhitelist(querySupport.getPropertyWhitelist()); visitor.setPropertyBlacklist(querySupport.getPropertyBlacklist()); diff --git a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilder.java b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilder.java index ee2b17c0..66832d67 100644 --- a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilder.java +++ b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilder.java @@ -15,6 +15,9 @@ */ public class JsonbExpressionBuilder { + private final String jsonbPathExistsTz; + private final String jsonbPathExists; + /** * The base json type. */ @@ -161,11 +164,19 @@ public ArgValue convert(String s) { Map.entry(BETWEEN, "(%1$s >= %2$s && %1$s <= %3$s)") ); + private static final String JSONB_PATH_EXISTS = "jsonb_path_exists"; + + private static final String JSONB_PATH_EXISTS_TZ = "jsonb_path_exists_tz"; + private final ComparisonOperator operator; private final String keyPath; private final List values; JsonbExpressionBuilder(ComparisonOperator operator, String keyPath, List args) { + this(operator, keyPath, args, null, null); + } + + JsonbExpressionBuilder(ComparisonOperator operator, String keyPath, List args, String jsonbPathExists, String jsonbPathExistsTz) { this.operator = Objects.requireNonNull(operator); this.keyPath = Objects.requireNonNull(keyPath); if(FORBIDDEN_NEGATION.contains(operator)) { @@ -185,6 +196,8 @@ public ArgValue convert(String s) { throw new IllegalArgumentException("Operator " + operator + " requires at least one value"); } this.values = findMoreTypes(operator, candidateValues); + this.jsonbPathExistsTz = jsonbPathExistsTz == null ? JSONB_PATH_EXISTS_TZ : jsonbPathExistsTz; + this.jsonbPathExists = jsonbPathExists == null ? JSONB_PATH_EXISTS : jsonbPathExists; } /** @@ -206,7 +219,7 @@ public JsonbPathExpression getJsonPathExpression() { List templateArguments = new ArrayList<>(); templateArguments.add(valueReference); templateArguments.addAll(valuesToCompare); - var function = isDateTimeTz ? JSONB_PATH_EXISTS_TZ : JSONB_PATH_EXISTS; + var function = isDateTimeTz ? jsonbPathExistsTz : jsonbPathExists; var expression = String.format("%s ? %s", targetPath, String.format(comparisonTemplate, templateArguments.toArray())); return new JsonbPathExpression(function, expression); } diff --git a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbSupport.java b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbSupport.java index 4372ce13..24dda423 100644 --- a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbSupport.java +++ b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/jsonb/JsonbSupport.java @@ -16,9 +16,7 @@ import io.github.perplexhub.rsql.ResolvedExpression; import jakarta.persistence.Column; import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.Expression; import jakarta.persistence.criteria.Path; -import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.Attribute; import jakarta.persistence.metamodel.ManagedType; import org.springframework.orm.jpa.vendor.Database; @@ -30,16 +28,6 @@ public class JsonbSupport { public static boolean DATE_TIME_SUPPORT = false; - /** - * Postgresql {@code jsonb_path_exists} function to use - */ - public static String JSONB_PATH_EXISTS = "jsonb_path_exists"; - - /** - * Postgresql {@code jsonb_path_exists_tz} function to use - */ - public static String JSONB_PATH_EXISTS_TZ = "jsonb_path_exists_tz"; - private static final Set JSON_SUPPORT = EnumSet.of(Database.POSTGRESQL); private static final Map NEGATE_OPERATORS = @@ -73,9 +61,9 @@ record JsonbPathExpression(String jsonbFunction, String jsonbPath) { } - public static ResolvedExpression jsonbPathExistsExpression(CriteriaBuilder builder, ComparisonNode node, Path attrPath) { + public static ResolvedExpression jsonbPathExistsExpression(CriteriaBuilder builder, ComparisonNode node, Path attrPath, String jsonbPathExists, String jsonbPathExistsTz) { var mayBeInvertedOperator = Optional.ofNullable(NEGATE_OPERATORS.get(node.getOperator())); - var jsb = new JsonbExpressionBuilder(mayBeInvertedOperator.orElse(node.getOperator()), node.getSelector(), node.getArguments()); + var jsb = new JsonbExpressionBuilder(mayBeInvertedOperator.orElse(node.getOperator()), node.getSelector(), node.getArguments(), jsonbPathExists, jsonbPathExistsTz); var expression = jsb.getJsonPathExpression(); return ResolvedExpression.ofJson(builder.function(expression.jsonbFunction, Boolean.class, attrPath, builder.literal(expression.jsonbPath)), mayBeInvertedOperator.isPresent()); diff --git a/rsql-jpa/src/test/java/io/github/perplexhub/rsql/RSQLJPASupportPostgresJsonTest.java b/rsql-jpa/src/test/java/io/github/perplexhub/rsql/RSQLJPASupportPostgresJsonTest.java index bd0d86af..b8c680bb 100644 --- a/rsql-jpa/src/test/java/io/github/perplexhub/rsql/RSQLJPASupportPostgresJsonTest.java +++ b/rsql-jpa/src/test/java/io/github/perplexhub/rsql/RSQLJPASupportPostgresJsonTest.java @@ -17,6 +17,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.orm.jpa.vendor.Database; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.jdbc.Sql; import java.util.Collection; import java.util.HashMap; @@ -542,9 +543,9 @@ private static Stream meltedTimeZone() { var e3 = new PostgresJsonEntity(Map.of("a", "2020-01-01T00:00:00")); var allCases = List.of(e1, e2, e3); return Stream.of( - arguments(allCases, "properties.a=ge=1970-01-02T00:00:00+00:00", List.of(e2, e3)), - arguments(allCases, "properties.a=ge=1970-01-02T00:00:00+01:00", List.of(e2, e3)), - arguments(allCases, "properties.a=lt=2022-01-01T00:00:00+01:00", List.of(e1, e2, e3)), + arguments(allCases, "properties.a=ge=1970-01-02T00:00:00+00:00", List.of(e2, e3)), + arguments(allCases, "properties.a=ge=1970-01-02T00:00:00+01:00", List.of(e2, e3)), + arguments(allCases, "properties.a=lt=2022-01-01T00:00:00+01:00", List.of(e1, e2, e3)), null ).filter(Objects::nonNull); } @@ -721,4 +722,23 @@ private static Map nullMap(String key) { nullValue.put(key, null); return nullValue; } + + @Sql(statements = "CREATE OR REPLACE FUNCTION my_jsonb_path_exists(arg1 jsonb,arg2 jsonpath) RETURNS boolean AS 'SELECT $1 @? $2' LANGUAGE 'sql' IMMUTABLE;") + @Sql(statements = "DROP FUNCTION IF EXISTS my_jsonb_path_exists;", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) + @ParameterizedTest + @MethodSource("data") + void testJsonSearchCustomFunction(List entities, String rsql, List expected) { + //given + repository.saveAllAndFlush(entities); + + //when + List result = repository.findAll(toSpecification(new QuerySupport.QuerySupportBuilder().rsqlQuery(rsql).jsonbPathExists("my_jsonb_path_exists").build())); + + //then + assertThat(result) + .hasSameSizeAs(expected) + .containsExactlyInAnyOrderElementsOf(expected); + + entities.forEach(e -> e.setId(null)); + } } diff --git a/rsql-jpa/src/test/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilderTest.java b/rsql-jpa/src/test/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilderTest.java index 28965ab3..a801b987 100644 --- a/rsql-jpa/src/test/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilderTest.java +++ b/rsql-jpa/src/test/java/io/github/perplexhub/rsql/jsonb/JsonbExpressionBuilderTest.java @@ -40,22 +40,11 @@ void testJsonbPathExpressionWithTemporal(ComparisonOperator operator, String key @ParameterizedTest @MethodSource("customized") void testJsonbPathExpressionCustomized(ComparisonOperator operator, String keyPath, List arguments, String expectedJsonbFunction, String expectedJsonbPath) { - String jsonbPathExists = JsonbSupport.JSONB_PATH_EXISTS; - String jsonbPathExistsTz = JsonbSupport.JSONB_PATH_EXISTS_TZ; - try { - JsonbSupport.JSONB_PATH_EXISTS = "my_jsonb_path_exists"; - JsonbSupport.JSONB_PATH_EXISTS_TZ = "my_jsonb_path_exists_tz"; - JsonbSupport.DATE_TIME_SUPPORT = true; - JsonbExpressionBuilder builder = new JsonbExpressionBuilder(operator, keyPath, arguments); - var expression = builder.getJsonPathExpression(); - assertEquals(expectedJsonbFunction, expression.jsonbFunction()); - assertEquals(expectedJsonbPath, expression.jsonbPath()); - } catch (Exception e) { - throw e; - } finally { - JsonbSupport.JSONB_PATH_EXISTS = jsonbPathExists; - JsonbSupport.JSONB_PATH_EXISTS_TZ = jsonbPathExistsTz; - } + JsonbSupport.DATE_TIME_SUPPORT = true; + JsonbExpressionBuilder builder = new JsonbExpressionBuilder(operator, keyPath, arguments, "my_jsonb_path_exists", "my_jsonb_path_exists_tz"); + var expression = builder.getJsonPathExpression(); + assertEquals(expectedJsonbFunction, expression.jsonbFunction()); + assertEquals(expectedJsonbPath, expression.jsonbPath()); } static Stream data() { From c1b8c390295c63d66f3b46a7d304a5a5975ac98e Mon Sep 17 00:00:00 2001 From: Martin Fekete Date: Tue, 19 Aug 2025 18:38:40 +0200 Subject: [PATCH 4/4] updated QuerySupport.toString --- .../src/main/java/io/github/perplexhub/rsql/QuerySupport.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/QuerySupport.java b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/QuerySupport.java index 7fffe5d5..5c156c19 100644 --- a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/QuerySupport.java +++ b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/QuerySupport.java @@ -40,7 +40,7 @@ public static class QuerySupportBuilder {} @Override public String toString() { - return String.format("%s,distinct:%b,propertyPathMapper:%s,customPredicates:%d,joinHints:%s,propertyWhitelist:%s,propertyBlacklist:%s", - rsqlQuery, distinct, propertyPathMapper, customPredicates == null ? 0 : customPredicates.size(), joinHints, propertyWhitelist, propertyBlacklist); + return String.format("%s,distinct:%b,propertyPathMapper:%s,customPredicates:%d,joinHints:%s,propertyWhitelist:%s,propertyBlacklist:%s,jsonbPathExists:%s,jsonbPathExistsTz:%s", + rsqlQuery, distinct, propertyPathMapper, customPredicates == null ? 0 : customPredicates.size(), joinHints, propertyWhitelist, propertyBlacklist, jsonbPathExists, jsonbPathExistsTz); } }