feat: add OR operator to QuerySpec constraints#108
feat: add OR operator to QuerySpec constraints#108javier-godoy wants to merge 2 commits intomasterfrom
Conversation
WalkthroughAdds OR/disjunction support: new DisjunctionConstraint type and factory, Constraint.or(...) convenience, transformer hook and JPA implementation combining sub-predicates with OR using LEFT joins, tests for OR behavior, and version bumps across Maven modules. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@backend-core-data-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.java`:
- Around line 173-175: The stream currently maps child constraints with
this::transform which bypasses the public unsupported-constraint guard and can
produce null entries; instead call the transformer’s public apply(...) for each
child so any ConstraintTransformerException is thrown immediately. Replace the
mapping in ConstraintTransformerJpaImpl where predicates are built (the
c.getConstraints() stream that produces predicates) to invoke apply(constraint)
for each child constraint (e.g., map(constraint -> apply(constraint))) so
unsupported constraints are surfaced rather than allowing nulls into the
Predicate[].
- Around line 171-176: transformDisjunctionConstraint currently maps child
constraints with this::transform (which returns null for unsupported
constraints) and uses path navigation that defaults to JoinType.INNER, causing
nullable associations to be filtered out before OR evaluation; change the
implementation to use apply() instead of transform() so unsupported child
constraints throw, and ensure path navigation invoked during disjunctions uses
left-join-safe handling (use LEFT joins for attribute path resolution when
building predicates for transformDisjunctionConstraint) so expressions like
"city.name = X OR id = Y" will include rows with null city; keep combining the
resulting Predicate[] with criteriaBuilder.or(...) as before.
In
`@backend-core-data-impl/src/test/java/com/flowingcode/backendcore/dao/jpa/JpaDaoSupportTest.java`:
- Around line 150-167: The tests testFilterWithOrConstraint and
testFilterWithOrConstraintPartialMatch rely on generated city names being
distinct; make the predicates deterministic by comparing on city.id (e.g.,
ConstraintBuilder.of("city","id").equal(...)) or by using fixed known names
instead of cities.get(...).getName() so the OR branches are unambiguous—update
the ConstraintBuilder calls in both tests (the ones using "city","name") to use
"city","id" (or fixed literals) and adjust expected counts if necessary.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 65232f81-59a7-4593-92e7-142f997b555d
📒 Files selected for processing (5)
backend-core-data-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.javabackend-core-data-impl/src/test/java/com/flowingcode/backendcore/dao/jpa/JpaDaoSupportTest.javabackend-core-model/src/main/java/com/flowingcode/backendcore/model/Constraint.javabackend-core-model/src/main/java/com/flowingcode/backendcore/model/ConstraintTransformer.javabackend-core-model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.java
...ata-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.java
Outdated
Show resolved
Hide resolved
...ata-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.java
Outdated
Show resolved
Hide resolved
backend-core-data-impl/src/test/java/com/flowingcode/backendcore/dao/jpa/JpaDaoSupportTest.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
♻️ Duplicate comments (1)
backend-core-data-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.java (1)
87-90:⚠️ Potential issue | 🟠 MajorLEFT-join disjunction can still reuse an INNER join and drop nullable rows.
At Line 89, existing joins are matched only by attribute name. If an INNER join was created earlier on the same path, the disjunction at Line 174 (which switches to LEFT) can still reuse that INNER join, so rows with null associations may still be filtered before the
ORis evaluated.Suggested fix
`@SuppressWarnings`("rawtypes") private From<?,?> join(From<?,?> source, String attributeName) { - Optional<Join> existingJoin = source.getJoins().stream().filter(join->join.getAttribute().getName().equals(attributeName)).map(join->(Join)join).findFirst(); + Optional<Join> existingJoin = source.getJoins().stream() + .map(join -> (Join) join) + .filter(join -> join.getAttribute().getName().equals(attributeName)) + .filter(join -> join.getJoinType() == currentJoinType) + .findFirst(); return existingJoin.orElseGet(()->source.join(attributeName, currentJoinType)); }Also applies to: 174-181
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend-core-data-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.java` around lines 87 - 90, The join reuse logic in join(From<?,?> source, String attributeName) matches only on attribute name and can return an INNER join when currentJoinType is LEFT; update the matching so you only reuse an existing Join if both the attribute name and the Join.getJoinType() equal the requested/currentJoinType, otherwise create a new join with source.join(attributeName, currentJoinType); apply the same change to the other join helper used around the disjunction (the overloaded join method at the 174-181 area) so LEFT joins are never replaced by previously-created INNER joins.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In
`@backend-core-data-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.java`:
- Around line 87-90: The join reuse logic in join(From<?,?> source, String
attributeName) matches only on attribute name and can return an INNER join when
currentJoinType is LEFT; update the matching so you only reuse an existing Join
if both the attribute name and the Join.getJoinType() equal the
requested/currentJoinType, otherwise create a new join with
source.join(attributeName, currentJoinType); apply the same change to the other
join helper used around the disjunction (the overloaded join method at the
174-181 area) so LEFT joins are never replaced by previously-created INNER
joins.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 012bb055-a583-4c99-8b5a-7dee1619ed7a
📒 Files selected for processing (2)
backend-core-data-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.javabackend-core-data-impl/src/test/java/com/flowingcode/backendcore/dao/jpa/JpaDaoSupportTest.java
16a2c21 to
7a5834f
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (2)
backend-core-model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.java (1)
39-44: Consider null-safety for constraint elements.The factory accepts varargs that could contain null elements, which would propagate to the list and potentially cause NPEs during transformation. The
firstparameter also lacks explicit null validation.💡 Proposed defensive implementation
public static DisjunctionConstraint of(Constraint first, Constraint... rest) { + Objects.requireNonNull(first, "first constraint must not be null"); List<Constraint> list = new java.util.ArrayList<>(); list.add(first); - list.addAll(Arrays.asList(rest)); + for (Constraint c : rest) { + list.add(Objects.requireNonNull(c, "constraint must not be null")); + } return new DisjunctionConstraint(list); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend-core-model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.java` around lines 39 - 44, The factory DisjunctionConstraint.of(Constraint first, Constraint... rest) should defensively validate inputs: throw a clear exception (e.g., NullPointerException or IllegalArgumentException) if first is null, and filter out any null entries from the varargs before constructing the list; update the method that builds the internal List<Constraint> so it only adds non-null elements from rest (or throws if an empty/invalid set is produced) and then passes that sanitized list into the DisjunctionConstraint constructor to avoid NPEs during later transformation/processing.backend-core-data-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.java (1)
84-89: Mutable state for join type introduced.The
currentJoinTypefield makes this class not thread-safe. This is acceptable if instances are created per-query (which appears to be the case from constructor usage), but consider adding a class-level Javadoc note about thread-safety expectations.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend-core-data-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.java` around lines 84 - 89, The class currently holds mutable state in the field currentJoinType (used by the join(From<?,?>, String) method), making instances not thread-safe; add a class-level Javadoc on ConstraintTransformerJpaImpl that clearly states instances are not thread-safe, that currentJoinType is mutable and that callers must create a new instance per query (referencing the constructor and the join(...) method), or alternatively remove the mutable field and pass JoinType as a parameter to join(...) to make instances thread-safe—include which approach you choose in the Javadoc so callers know usage expectations.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In
`@backend-core-data-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.java`:
- Around line 84-89: The class currently holds mutable state in the field
currentJoinType (used by the join(From<?,?>, String) method), making instances
not thread-safe; add a class-level Javadoc on ConstraintTransformerJpaImpl that
clearly states instances are not thread-safe, that currentJoinType is mutable
and that callers must create a new instance per query (referencing the
constructor and the join(...) method), or alternatively remove the mutable field
and pass JoinType as a parameter to join(...) to make instances
thread-safe—include which approach you choose in the Javadoc so callers know
usage expectations.
In
`@backend-core-model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.java`:
- Around line 39-44: The factory DisjunctionConstraint.of(Constraint first,
Constraint... rest) should defensively validate inputs: throw a clear exception
(e.g., NullPointerException or IllegalArgumentException) if first is null, and
filter out any null entries from the varargs before constructing the list;
update the method that builds the internal List<Constraint> so it only adds
non-null elements from rest (or throws if an empty/invalid set is produced) and
then passes that sanitized list into the DisjunctionConstraint constructor to
avoid NPEs during later transformation/processing.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 37b60e1c-ddd8-4860-ac1c-ec7009d5140b
📒 Files selected for processing (12)
backend-core-business-impl/pom.xmlbackend-core-business-spring-impl/pom.xmlbackend-core-business/pom.xmlbackend-core-data-impl/pom.xmlbackend-core-data-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.javabackend-core-data-impl/src/test/java/com/flowingcode/backendcore/dao/jpa/JpaDaoSupportTest.javabackend-core-data/pom.xmlbackend-core-model/pom.xmlbackend-core-model/src/main/java/com/flowingcode/backendcore/model/Constraint.javabackend-core-model/src/main/java/com/flowingcode/backendcore/model/ConstraintTransformer.javabackend-core-model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.javapom.xml
🚧 Files skipped from review as they are similar to previous changes (8)
- pom.xml
- backend-core-data/pom.xml
- backend-core-business/pom.xml
- backend-core-data-impl/src/test/java/com/flowingcode/backendcore/dao/jpa/JpaDaoSupportTest.java
- backend-core-model/src/main/java/com/flowingcode/backendcore/model/Constraint.java
- backend-core-model/pom.xml
- backend-core-business-spring-impl/pom.xml
- backend-core-data-impl/pom.xml
There was a problem hiding this comment.
🧹 Nitpick comments (1)
backend-core-model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.java (1)
33-46: Consider making the constraint list immutable.The
@Getteronconstraintsexposes the internal mutableArrayList, allowing callers to modify it after construction. For a value object representing a logical OR, immutability is preferred.♻️ Proposed fix to return an unmodifiable list
+import java.util.Collections; ... `@Getter` `@RequiredArgsConstructor` `@FieldDefaults`(level = AccessLevel.PRIVATE, makeFinal = true) public class DisjunctionConstraint implements Constraint { - `@NonNull` List<Constraint> constraints; + `@NonNull` List<Constraint> constraints; + + public List<Constraint> getConstraints() { + return Collections.unmodifiableList(constraints); + } public static DisjunctionConstraint of(Constraint first, Constraint... rest) { List<Constraint> list = new java.util.ArrayList<>(); list.add(Objects.requireNonNull(first, "constraint must not be null")); for (Constraint c : rest) { list.add(Objects.requireNonNull(c, "constraint must not be null")); } - return new DisjunctionConstraint(list); + return new DisjunctionConstraint(Collections.unmodifiableList(list)); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend-core-model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.java` around lines 33 - 46, The constraints List exposed by DisjunctionConstraint (field constraints and getter generated by `@Getter`) is currently mutable; make it immutable by wrapping the list used in the constructor/factory (e.g., in DisjunctionConstraint.of(Constraint first, Constraint... rest)) with an unmodifiable copy (for example use Collections.unmodifiableList(new ArrayList<>(list)) or List.copyOf(list)) before constructing the DisjunctionConstraint so callers cannot modify the internal list after creation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In
`@backend-core-model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.java`:
- Around line 33-46: The constraints List exposed by DisjunctionConstraint
(field constraints and getter generated by `@Getter`) is currently mutable; make
it immutable by wrapping the list used in the constructor/factory (e.g., in
DisjunctionConstraint.of(Constraint first, Constraint... rest)) with an
unmodifiable copy (for example use Collections.unmodifiableList(new
ArrayList<>(list)) or List.copyOf(list)) before constructing the
DisjunctionConstraint so callers cannot modify the internal list after creation.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e6fee4fd-4be0-4f36-aef8-eeeb1e9ed6f2
📒 Files selected for processing (2)
backend-core-data-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.javabackend-core-model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.java
fe7413f to
b75b25d
Compare
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
backend-core-model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.java (1)
32-37: Consider restricting constructor visibility (optional).The Lombok-generated public constructor allows bypassing the factory method's per-element null validation. If you want to enforce the factory pattern:
♻️ Optional: Make constructor private
`@Getter` -@RequiredArgsConstructor +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) `@FieldDefaults`(level = AccessLevel.PRIVATE, makeFinal = true) public class DisjunctionConstraint implements Constraint {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend-core-model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.java` around lines 32 - 37, The public constructor generated by Lombok (`@RequiredArgsConstructor`) on DisjunctionConstraint lets callers bypass the factory null-checks for the constraints field; change the constructor visibility to private by updating the Lombok annotation to generate a private constructor (e.g., `@RequiredArgsConstructor`(access = AccessLevel.PRIVATE)) so callers must use the factory method that enforces per-element null validation for the List<Constraint> constraints.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@backend-core-model/src/main/java/com/flowingcode/backendcore/model/Constraint.java`:
- Around line 39-47: The or(Constraint first, Constraint... rest) path assumes
rest is non-null and will NPE in prepend(...) for calls like or(x,
(Constraint[]) null); modify prepend(Constraint first, Constraint[] rest) (or
add a null-guard in or()) to treat a null rest as an empty array before creating
the result array and calling System.arraycopy — e.g., normalize rest to an empty
Constraint[] when null so the array creation and copy logic work safely and
subsequent constraint-level null validations can run.
---
Nitpick comments:
In
`@backend-core-model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.java`:
- Around line 32-37: The public constructor generated by Lombok
(`@RequiredArgsConstructor`) on DisjunctionConstraint lets callers bypass the
factory null-checks for the constraints field; change the constructor visibility
to private by updating the Lombok annotation to generate a private constructor
(e.g., `@RequiredArgsConstructor`(access = AccessLevel.PRIVATE)) so callers must
use the factory method that enforces per-element null validation for the
List<Constraint> constraints.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 60535b5a-a58f-4190-8082-a5ec1579447d
📒 Files selected for processing (12)
backend-core-business-impl/pom.xmlbackend-core-business-spring-impl/pom.xmlbackend-core-business/pom.xmlbackend-core-data-impl/pom.xmlbackend-core-data-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.javabackend-core-data-impl/src/test/java/com/flowingcode/backendcore/dao/jpa/JpaDaoSupportTest.javabackend-core-data/pom.xmlbackend-core-model/pom.xmlbackend-core-model/src/main/java/com/flowingcode/backendcore/model/Constraint.javabackend-core-model/src/main/java/com/flowingcode/backendcore/model/ConstraintTransformer.javabackend-core-model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.javapom.xml
| default Constraint or(Constraint first, Constraint... rest) { | ||
| return DisjunctionConstraint.of(this, prepend(first, rest)); | ||
| } | ||
|
|
||
| private static Constraint[] prepend(Constraint first, Constraint[] rest) { | ||
| Constraint[] result = new Constraint[1 + rest.length]; | ||
| result[0] = first; | ||
| System.arraycopy(rest, 0, result, 1, rest.length); | ||
| return result; |
There was a problem hiding this comment.
Handle explicit null varargs defensively in or(...).
Line 43 assumes rest is non-null. A call like or(x, (Constraint[]) null) throws an NPE in prepend(...) before constraint-level null validation runs.
Suggested fix
import com.flowingcode.backendcore.model.constraints.DisjunctionConstraint;
import com.flowingcode.backendcore.model.constraints.NegatedConstraint;
+import java.util.Objects;
@@
default Constraint or(Constraint first, Constraint... rest) {
- return DisjunctionConstraint.of(this, prepend(first, rest));
+ return DisjunctionConstraint.of(this, prepend(first, Objects.requireNonNull(rest, "rest must not be null")));
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| default Constraint or(Constraint first, Constraint... rest) { | |
| return DisjunctionConstraint.of(this, prepend(first, rest)); | |
| } | |
| private static Constraint[] prepend(Constraint first, Constraint[] rest) { | |
| Constraint[] result = new Constraint[1 + rest.length]; | |
| result[0] = first; | |
| System.arraycopy(rest, 0, result, 1, rest.length); | |
| return result; | |
| default Constraint or(Constraint first, Constraint... rest) { | |
| return DisjunctionConstraint.of(this, prepend(first, Objects.requireNonNull(rest, "rest must not be null"))); | |
| } | |
| private static Constraint[] prepend(Constraint first, Constraint[] rest) { | |
| Constraint[] result = new Constraint[1 + rest.length]; | |
| result[0] = first; | |
| System.arraycopy(rest, 0, result, 1, rest.length); | |
| return result; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@backend-core-model/src/main/java/com/flowingcode/backendcore/model/Constraint.java`
around lines 39 - 47, The or(Constraint first, Constraint... rest) path assumes
rest is non-null and will NPE in prepend(...) for calls like or(x,
(Constraint[]) null); modify prepend(Constraint first, Constraint[] rest) (or
add a null-guard in or()) to treat a null rest as an empty array before creating
the result array and calling System.arraycopy — e.g., normalize rest to an empty
Constraint[] when null so the array creation and copy logic work safely and
subsequent constraint-level null validations can run.
There was a problem hiding this comment.
@coderabbitai please check if the comment has been addressed.
There was a problem hiding this comment.
@javier-godoy, based on the current file content, the comment has not been addressed yet. The or(Constraint first, Constraint... rest) method still passes rest directly to prepend(...) without any null-guard:
default Constraint or(Constraint first, Constraint... rest) {
return DisjunctionConstraint.of(this, prepend(first, rest));
}A call like or(x, (Constraint[]) null) will still throw an NPE inside prepend(...) at rest.length before any constraint-level validation runs. The suggested fix (Objects.requireNonNull(rest, "rest must not be null")) has not been applied.
There was a problem hiding this comment.
@coderabbitai Note that DisjunctionConstraint.of already checks whether the varargs is null
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
fd "DisjunctionConstraint.java" --exec cat {}
Length of output: 1759
@javier-godoy, you're right that DisjunctionConstraint.of does include a null check (Objects.requireNonNull(rest, "constraints must not be null")). However, that check is never reached in this code path when rest is null. The call chain is:
or(first, null)→ callsprepend(first, null)- In
prepend:new Constraint[1 + rest.length]→ NPE here (no message), beforeDisjunctionConstraint.ofis ever invoked.
So the null guard in DisjunctionConstraint.of doesn't cover this case — prepend fails first. The original concern remains: a caller passing or(x, (Constraint[]) null) gets an NPE with no helpful message, whereas the guard in DisjunctionConstraint.of would give "constraints must not be null".
That said, explicitly casting null to Constraint[] is a very unusual call pattern, and both paths still fail fast with an NPE. If you consider this acceptable behavior, I can close the comment.
b75b25d to
90692ec
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@backend-core-model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.java`:
- Around line 39-44: DisjunctionConstraint.of currently assumes the varargs
array 'rest' is non-null and will throw an implicit NPE in the for-loop; add an
explicit null check for the varargs container before iterating (e.g.,
Objects.requireNonNull(rest, "constraints must not be null")) so callers calling
of(first, (Constraint[]) null) get a predictable error, then continue to
validate each element in 'rest' with Objects.requireNonNull as already done.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3e688aad-15c0-42c2-b24c-b0b3f2181db7
📒 Files selected for processing (5)
backend-core-data-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.javabackend-core-data-impl/src/test/java/com/flowingcode/backendcore/dao/jpa/JpaDaoSupportTest.javabackend-core-model/src/main/java/com/flowingcode/backendcore/model/Constraint.javabackend-core-model/src/main/java/com/flowingcode/backendcore/model/ConstraintTransformer.javabackend-core-model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.java
🚧 Files skipped from review as they are similar to previous changes (3)
- backend-core-model/src/main/java/com/flowingcode/backendcore/model/Constraint.java
- backend-core-model/src/main/java/com/flowingcode/backendcore/model/ConstraintTransformer.java
- backend-core-data-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.java
...model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.java
Show resolved
Hide resolved
90692ec to
4c30971
Compare
|
There was a problem hiding this comment.
♻️ Duplicate comments (1)
backend-core-model/src/main/java/com/flowingcode/backendcore/model/Constraint.java (1)
39-47:⚠️ Potential issue | 🟡 MinorGuard the varargs container before
prepend(...).
or(x, (Constraint[]) null)still blows up onrest.lengthinsideprepend()beforeDisjunctionConstraint.of(...)can validate anything. Treat a null varargs container as an empty array here so this path behaves predictably.Suggested fix
private static Constraint[] prepend(Constraint first, Constraint[] rest) { + rest = rest == null ? new Constraint[0] : rest; Constraint[] result = new Constraint[1 + rest.length]; result[0] = first; System.arraycopy(rest, 0, result, 1, rest.length); return result; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend-core-model/src/main/java/com/flowingcode/backendcore/model/Constraint.java` around lines 39 - 47, The prepend(...) helper doesn't guard against a null varargs array, so calling or(x, (Constraint[]) null) throws on rest.length before DisjunctionConstraint.of(...) can validate; update the code to treat a null rest as an empty array (e.g., if rest == null then set rest = new Constraint[0]) either inside prepend(Constraint first, Constraint[] rest) or by handling null before calling prepend in or(...), ensuring DisjunctionConstraint.of(this, prepend(...)) always receives a non-null array.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In
`@backend-core-model/src/main/java/com/flowingcode/backendcore/model/Constraint.java`:
- Around line 39-47: The prepend(...) helper doesn't guard against a null
varargs array, so calling or(x, (Constraint[]) null) throws on rest.length
before DisjunctionConstraint.of(...) can validate; update the code to treat a
null rest as an empty array (e.g., if rest == null then set rest = new
Constraint[0]) either inside prepend(Constraint first, Constraint[] rest) or by
handling null before calling prepend in or(...), ensuring
DisjunctionConstraint.of(this, prepend(...)) always receives a non-null array.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: cff07aaf-5473-4d1c-9fe5-2e15f414dba8
📒 Files selected for processing (5)
backend-core-data-impl/src/main/java/com/flowingcode/backendcore/dao/jpa/ConstraintTransformerJpaImpl.javabackend-core-data-impl/src/test/java/com/flowingcode/backendcore/dao/jpa/JpaDaoSupportTest.javabackend-core-model/src/main/java/com/flowingcode/backendcore/model/Constraint.javabackend-core-model/src/main/java/com/flowingcode/backendcore/model/ConstraintTransformer.javabackend-core-model/src/main/java/com/flowingcode/backendcore/model/constraints/DisjunctionConstraint.java
🚧 Files skipped from review as they are similar to previous changes (1)
- backend-core-model/src/main/java/com/flowingcode/backendcore/model/ConstraintTransformer.java



Close #61
Summary by CodeRabbit
New Features
Tests
Chores