File tree Expand file tree Collapse file tree 2 files changed +23
-7
lines changed
main/java/org/springframework/data/jpa/domain
test/java/org/springframework/data/jpa/domain Expand file tree Collapse file tree 2 files changed +23
-7
lines changed Original file line number Diff line number Diff line change 2929
3030/**
3131 * Specification in the sense of Domain Driven Design.
32+ * <p>
33+ * Specifications can be composed into higher order functions from other specifications using
34+ * {@link #and(Specification)}, {@link #or(Specification)} or factory methods such as {@link #allOf(Iterable)}.
35+ * <p>
36+ * Composition considers whether one or more specifications contribute to the overall predicate by returning a
37+ * {@link Predicate} or {@literal null}. Specifications returning {@literal null}, such as {@link #unrestricted()}, are
38+ * considered to not contribute to the overall predicate, and their result is not considered in the final predicate.
3239 *
3340 * @author Oliver Gierke
3441 * @author Thomas Darimont
3845 * @author Jens Schauder
3946 * @author Daniel Shuy
4047 * @author Sergey Rukin
48+ * @author Peter Aisher
4149 */
4250@ FunctionalInterface
4351public interface Specification <T > extends Serializable {
@@ -65,7 +73,16 @@ static <T> Specification<T> not(@Nullable Specification<T> spec) {
6573 }
6674
6775 /**
68- * Simple static factory method to create a specification matching all objects.
76+ * Simple static factory method to create a specification which does not participate in matching. The specification
77+ * returned is {@code null}-like, and is elided in all operations.
78+ *
79+ * <pre>
80+ * {@code
81+ * unrestricted().and(other) // consider only `other`
82+ * unrestricted().or(other) // consider only `other`
83+ * not(unrestricted()) // equivalent to `unrestricted()`
84+ * }
85+ * </pre>
6986 *
7087 * @param <T> the type of the {@link Root} the resulting {@literal Specification} operates on.
7188 * @return guaranteed to be not {@literal null}.
Original file line number Diff line number Diff line change 4545 * @author Jens Schauder
4646 * @author Mark Paluch
4747 * @author Daniel Shuy
48+ * @author Peter Aisher
4849 */
4950@ SuppressWarnings ({ "unchecked" , "deprecation" , "removal" })
5051@ ExtendWith (MockitoExtension .class )
@@ -209,15 +210,13 @@ void orCombinesSpecificationsInOrder() {
209210 verify (builder ).or (firstPredicate , secondPredicate );
210211 }
211212
212- @ Test // GH-3849
213+ @ Test // GH-3849, GH-4023
213214 void notWithNullPredicate () {
214215
215- when ( builder . disjunction ()). thenReturn ( mock ( Predicate . class ));
216+ Specification < Object > notSpec = Specification . not ( Specification . unrestricted ( ));
216217
217- Specification <Object > notSpec = Specification .not ((r , q , cb ) -> null );
218-
219- assertThat (notSpec .toPredicate (root , query , builder )).isNotNull ();
220- verify (builder ).disjunction ();
218+ assertThat (notSpec .toPredicate (root , query , builder )).isNull ();
219+ verifyNoInteractions (builder );
221220 }
222221
223222 static class SerializableSpecification implements Serializable , Specification <Object > {
You can’t perform that action at this time.
0 commit comments