20
20
import javax .persistence .criteria .Predicate ;
21
21
import javax .persistence .criteria .Root ;
22
22
23
- import org .springframework .util .Assert ;
24
-
25
23
/**
26
24
* Helper class to easily combine {@link Specification} instances.
27
25
*
28
26
* @author Oliver Gierke
29
27
*/
30
28
public class Specifications <T > implements Specification <T > {
31
29
32
- private static final String NOT_NULL = "Specification given to %s(…) must not be null!" ;
33
-
34
30
private final Specification <T > spec ;
35
31
36
32
/**
37
33
* Creates a new {@link Specifications} wrapper for the given {@link Specification}.
38
34
*
39
- * @param spec must not be {@literal null}.
35
+ * @param spec can be {@literal null}.
40
36
*/
41
37
private Specifications (Specification <T > spec ) {
42
38
this .spec = spec ;
@@ -46,29 +42,30 @@ private Specifications(Specification<T> spec) {
46
42
* Simple static factory method to add some syntactic sugar around a {@link Specification}.
47
43
*
48
44
* @param <T>
49
- * @param spec must not be {@literal null}.
45
+ * @param spec can be {@literal null}.
50
46
* @return
51
47
*/
52
48
public static <T > Specifications <T > where (Specification <T > spec ) {
53
-
54
- Assert .notNull (spec , String .format (NOT_NULL , "where" ));
55
49
return new Specifications <T >(spec );
56
50
}
57
51
58
52
/**
59
53
* ANDs the given {@link Specification} to the current one.
60
54
*
61
55
* @param <T>
62
- * @param other must not be {@literal null}.
56
+ * @param other can be {@literal null}.
63
57
* @return
64
58
*/
65
59
public Specifications <T > and (final Specification <T > other ) {
66
60
67
- Assert .notNull (spec , String .format (NOT_NULL , "and" ));
68
-
69
61
return new Specifications <T >(new Specification <T >() {
70
62
public Predicate toPredicate (Root <T > root , CriteriaQuery <?> query , CriteriaBuilder builder ) {
71
- return builder .and (spec .toPredicate (root , query , builder ), other .toPredicate (root , query , builder ));
63
+
64
+ Predicate otherPredicate = other == null ? null : other .toPredicate (root , query , builder );
65
+ Predicate thisPredicate = spec == null ? null : spec .toPredicate (root , query , builder );
66
+
67
+ return thisPredicate == null ? otherPredicate : otherPredicate == null ? thisPredicate : builder .and (
68
+ thisPredicate , otherPredicate );
72
69
}
73
70
});
74
71
}
@@ -77,16 +74,19 @@ public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuild
77
74
* ORs the given specification to the current one.
78
75
*
79
76
* @param <T>
80
- * @param other must not be {@literal null}.
77
+ * @param other can be {@literal null}.
81
78
* @return
82
79
*/
83
80
public Specifications <T > or (final Specification <T > other ) {
84
81
85
- Assert .notNull (spec , String .format (NOT_NULL , "or" ));
86
-
87
82
return new Specifications <T >(new Specification <T >() {
88
83
public Predicate toPredicate (Root <T > root , CriteriaQuery <?> query , CriteriaBuilder builder ) {
89
- return builder .or (spec .toPredicate (root , query , builder ), other .toPredicate (root , query , builder ));
84
+
85
+ Predicate otherPredicate = other == null ? null : other .toPredicate (root , query , builder );
86
+ Predicate thisPredicate = spec == null ? null : spec .toPredicate (root , query , builder );
87
+
88
+ return thisPredicate == null ? otherPredicate : otherPredicate == null ? thisPredicate : builder .or (
89
+ thisPredicate , otherPredicate );
90
90
}
91
91
});
92
92
}
@@ -95,16 +95,13 @@ public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuild
95
95
* Negates the given {@link Specification}.
96
96
*
97
97
* @param <T>
98
- * @param spec must not be {@literal null}.
98
+ * @param spec can be {@literal null}.
99
99
* @return
100
100
*/
101
101
public static <T > Specifications <T > not (final Specification <T > spec ) {
102
-
103
- Assert .notNull (spec , String .format (NOT_NULL , "not" ));
104
-
105
102
return new Specifications <T >(new Specification <T >() {
106
103
public Predicate toPredicate (Root <T > root , CriteriaQuery <?> query , CriteriaBuilder builder ) {
107
- return builder .not (spec .toPredicate (root , query , builder ));
104
+ return spec == null ? null : builder .not (spec .toPredicate (root , query , builder ));
108
105
}
109
106
});
110
107
}
@@ -114,6 +111,6 @@ public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuild
114
111
* @see org.springframework.data.jpa.domain.Specification#toPredicate(javax.persistence.criteria.Root, javax.persistence.criteria.CriteriaQuery, javax.persistence.criteria.CriteriaBuilder)
115
112
*/
116
113
public Predicate toPredicate (Root <T > root , CriteriaQuery <?> query , CriteriaBuilder builder ) {
117
- return spec .toPredicate (root , query , builder );
114
+ return spec == null ? null : spec .toPredicate (root , query , builder );
118
115
}
119
116
}
0 commit comments