18
18
import static com .github .mhewedy .expressions .Expression .*;
19
19
import static java .util .Collections .singletonList ;
20
20
import static java .util .stream .Collectors .toList ;
21
+ import static javax .persistence .metamodel .Attribute .PersistentAttributeType ;
21
22
22
23
class ExpressionsPredicateBuilder {
23
24
24
- static <T > Predicate getPredicate (Root <T > root , CriteriaBuilder cb , Expressions expressions ) {
25
+ static <T > Predicate getPredicate (Root <T > root , CriteriaQuery <?> query , CriteriaBuilder cb , Expressions expressions ) {
25
26
26
27
Assert .notNull (expressions , "expressions must not be null!" );
27
28
28
- List <Predicate > predicates = getPredicates (cb ,
29
+ List <Predicate > predicates = getPredicates (query , cb ,
29
30
root ,
30
31
root .getModel (),
31
32
expressions .getExpressions ());
@@ -44,7 +45,7 @@ static <T> Predicate getPredicate(Root<T> root, CriteriaBuilder cb, Expressions
44
45
}
45
46
46
47
@ SuppressWarnings ({"rawtypes" , "unchecked" })
47
- private static List <Predicate > getPredicates (CriteriaBuilder cb ,
48
+ private static List <Predicate > getPredicates (CriteriaQuery <?> query , CriteriaBuilder cb ,
48
49
Path <?> from , ManagedType <?> type ,
49
50
List <Expression > expressions ) {
50
51
@@ -60,12 +61,16 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
60
61
Attribute <?, ?> attribute = getAttribute (type , field );
61
62
62
63
if (attribute .isAssociation ()) {
64
+ if (attribute instanceof PluralAttribute ) {
65
+ query .distinct (true );
66
+ }
67
+
63
68
final String subField = extractSubField (singularExpression .field );
64
69
if (!subField .isEmpty ()) {
65
70
final SingularExpression subExpression =
66
71
new SingularExpression (subField , singularExpression .operator , singularExpression .value );
67
72
predicates .addAll (
68
- getPredicates (cb ,
73
+ getPredicates (query , cb ,
69
74
reuseOrCreateJoin ((From <?, ?>) from , attribute , field ),
70
75
extractSubFieldType (attribute ),
71
76
singletonList (subExpression )
@@ -77,7 +82,7 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
77
82
78
83
Path exprPath = from .get ((SingularAttribute ) attribute );
79
84
80
- if (Attribute . PersistentAttributeType .EMBEDDED == attribute .getPersistentAttributeType ()) {
85
+ if (PersistentAttributeType .EMBEDDED == attribute .getPersistentAttributeType ()) {
81
86
final String subField = extractSubField (singularExpression .field );
82
87
attribute = extractSubFieldType (attribute ).getAttribute (subField );
83
88
exprPath = exprPath .get ((SingularAttribute ) attribute );
@@ -114,7 +119,7 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
114
119
predicate = cb .greaterThan (exprPath , (Comparable ) attributeValue );
115
120
} else {
116
121
throw new IllegalArgumentException ("field should be Number or Comparable: " +
117
- singularExpression );
122
+ singularExpression );
118
123
}
119
124
break ;
120
125
case $gte :
@@ -124,7 +129,7 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
124
129
predicate = cb .greaterThanOrEqualTo (exprPath , (Comparable ) attributeValue );
125
130
} else {
126
131
throw new IllegalArgumentException ("field should be Number or Comparable: " +
127
- singularExpression );
132
+ singularExpression );
128
133
}
129
134
break ;
130
135
case $lt :
@@ -134,7 +139,7 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
134
139
predicate = cb .lessThan (exprPath , (Comparable ) attributeValue );
135
140
} else {
136
141
throw new IllegalArgumentException ("field should be Number or Comparable: " +
137
- singularExpression );
142
+ singularExpression );
138
143
}
139
144
break ;
140
145
case $lte :
@@ -144,7 +149,7 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
144
149
predicate = cb .lessThanOrEqualTo (exprPath , (Comparable ) attributeValue );
145
150
} else {
146
151
throw new IllegalArgumentException ("field should be Number or Comparable: " +
147
- singularExpression );
152
+ singularExpression );
148
153
}
149
154
break ;
150
155
// like
@@ -179,12 +184,16 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
179
184
Attribute <?, ?> attribute = getAttribute (type , field );
180
185
181
186
if (attribute .isAssociation ()) {
187
+ if (attribute instanceof PluralAttribute ) {
188
+ query .distinct (true );
189
+ }
190
+
182
191
final String subField = extractSubField (listExpression .field );
183
192
if (!subField .isEmpty ()) {
184
193
final ListExpression subExpression =
185
194
new ListExpression (subField , listExpression .operator , listExpression .values );
186
195
predicates .addAll (
187
- getPredicates (cb ,
196
+ getPredicates (query , cb ,
188
197
reuseOrCreateJoin ((From <?, ?>) from , attribute , field ),
189
198
extractSubFieldType (attribute ),
190
199
singletonList (subExpression )
@@ -196,7 +205,7 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
196
205
197
206
Path exprPath = from .get ((SingularAttribute ) attribute );
198
207
199
- if (Attribute . PersistentAttributeType .EMBEDDED == attribute .getPersistentAttributeType ()) {
208
+ if (PersistentAttributeType .EMBEDDED == attribute .getPersistentAttributeType ()) {
200
209
final String subField = extractSubField (listExpression .field );
201
210
attribute = extractSubFieldType (attribute ).getAttribute (subField );
202
211
exprPath = exprPath .get ((SingularAttribute ) attribute );
@@ -227,13 +236,13 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
227
236
228
237
} else if (expression instanceof OrExpression ) {
229
238
predicates .add (cb .or (
230
- getPredicates (cb , from , type ,
239
+ getPredicates (query , cb , from , type ,
231
240
((OrExpression ) expression ).expressions ).toArray (new Predicate [0 ])
232
241
));
233
242
234
243
} else if (expression instanceof AndExpression ) {
235
244
predicates .add (cb .and (
236
- getPredicates (cb , from , type ,
245
+ getPredicates (query , cb , from , type ,
237
246
((AndExpression ) expression ).expressions ).toArray (new Predicate [0 ])
238
247
));
239
248
}
@@ -249,7 +258,7 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
249
258
throw new IllegalArgumentException (
250
259
String .format (
251
260
"Unable to locate attribute with the given name [%s] on this ManagedType [%s]," +
252
- " Are you sure this ManagedType or one of its ancestors contains such attribute?" ,
261
+ " Are you sure this ManagedType or one of its ancestors contains such attribute?" ,
253
262
field ,
254
263
type .getJavaType ().getName ()
255
264
)
0 commit comments