Polishing.

Add fix to Update, Delete, and PredicateSpecification. Reformat code. Refine tests.

See #3849
Original pull request: #3856
This commit is contained in:
Mark Paluch
2025-05-05 14:13:17 +02:00
parent dc854df741
commit 41bfd415ca
6 changed files with 42 additions and 9 deletions

View File

@@ -24,9 +24,9 @@ import java.io.Serializable;
import java.util.Arrays;
import java.util.stream.StreamSupport;
import org.springframework.lang.CheckReturnValue;
import org.jspecify.annotations.Nullable;
import org.springframework.lang.CheckReturnValue;
import org.springframework.lang.Contract;
import org.springframework.util.Assert;
@@ -159,7 +159,7 @@ public interface DeleteSpecification<T> extends Serializable {
return (root, delete, builder) -> {
Predicate predicate = spec.toPredicate(root, delete, builder);
return predicate != null ? builder.not(predicate) : null;
return predicate != null ? builder.not(predicate) : builder.disjunction();
};
}

View File

@@ -23,9 +23,9 @@ import java.io.Serializable;
import java.util.Arrays;
import java.util.stream.StreamSupport;
import org.springframework.lang.CheckReturnValue;
import org.jspecify.annotations.Nullable;
import org.springframework.lang.CheckReturnValue;
import org.springframework.lang.Contract;
import org.springframework.util.Assert;
@@ -113,7 +113,7 @@ public interface PredicateSpecification<T> extends Serializable {
return (root, builder) -> {
Predicate predicate = spec.toPredicate(root, builder);
return predicate != null ? builder.not(predicate) : null;
return predicate != null ? builder.not(predicate) : builder.disjunction();
};
}

View File

@@ -24,9 +24,9 @@ import java.io.Serializable;
import java.util.Arrays;
import java.util.stream.StreamSupport;
import org.springframework.lang.CheckReturnValue;
import org.jspecify.annotations.Nullable;
import org.springframework.lang.CheckReturnValue;
import org.springframework.lang.Contract;
import org.springframework.util.Assert;
@@ -180,7 +180,7 @@ public interface UpdateSpecification<T> extends Serializable {
return (root, update, builder) -> {
Predicate predicate = spec.toPredicate(root, update, builder);
return predicate != null ? builder.not(predicate) : null;
return predicate != null ? builder.not(predicate) : builder.disjunction();
};
}

View File

@@ -160,6 +160,17 @@ class DeleteSpecificationUnitTests implements Serializable {
verify(builder).or(firstPredicate, secondPredicate);
}
@Test // GH-3849
void notWithNullPredicate() {
when(builder.disjunction()).thenReturn(mock(Predicate.class));
DeleteSpecification<Object> notSpec = DeleteSpecification.not((r, q, cb) -> null);
assertThat(notSpec.toPredicate(root, delete, builder)).isNotNull();
verify(builder).disjunction();
}
static class SerializableSpecification implements Serializable, DeleteSpecification<Object> {
@Override

View File

@@ -158,6 +158,17 @@ class PredicateSpecificationUnitTests implements Serializable {
verify(builder).or(firstPredicate, secondPredicate);
}
@Test // GH-3849
void notWithNullPredicate() {
when(builder.disjunction()).thenReturn(mock(Predicate.class));
PredicateSpecification<Object> notSpec = PredicateSpecification.not((r, cb) -> null);
assertThat(notSpec.toPredicate(root, builder)).isNotNull();
verify(builder).disjunction();
}
static class SerializableSpecification implements Serializable, PredicateSpecification<Object> {
@Override

View File

@@ -160,6 +160,17 @@ class UpdateSpecificationUnitTests implements Serializable {
verify(builder).or(firstPredicate, secondPredicate);
}
@Test // GH-3849
void notWithNullPredicate() {
when(builder.disjunction()).thenReturn(mock(Predicate.class));
UpdateSpecification<Object> notSpec = UpdateSpecification.not((r, q, cb) -> null);
assertThat(notSpec.toPredicate(root, update, builder)).isNotNull();
verify(builder).disjunction();
}
static class SerializableSpecification implements Serializable, UpdateSpecification<Object> {
@Override