1818import static com .github .mhewedy .expressions .Expression .*;
1919import static java .util .Collections .singletonList ;
2020import static java .util .stream .Collectors .toList ;
21+ import static javax .persistence .metamodel .Attribute .PersistentAttributeType ;
2122
2223class ExpressionsPredicateBuilder {
2324
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 ) {
2526
2627 Assert .notNull (expressions , "expressions must not be null!" );
2728
28- List <Predicate > predicates = getPredicates (cb ,
29+ List <Predicate > predicates = getPredicates (query , cb ,
2930 root ,
3031 root .getModel (),
3132 expressions .getExpressions ());
@@ -44,7 +45,7 @@ static <T> Predicate getPredicate(Root<T> root, CriteriaBuilder cb, Expressions
4445 }
4546
4647 @ SuppressWarnings ({"rawtypes" , "unchecked" })
47- private static List <Predicate > getPredicates (CriteriaBuilder cb ,
48+ private static List <Predicate > getPredicates (CriteriaQuery <?> query , CriteriaBuilder cb ,
4849 Path <?> from , ManagedType <?> type ,
4950 List <Expression > expressions ) {
5051
@@ -60,12 +61,16 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
6061 Attribute <?, ?> attribute = getAttribute (type , field );
6162
6263 if (attribute .isAssociation ()) {
64+ if (attribute instanceof PluralAttribute ) {
65+ query .distinct (true );
66+ }
67+
6368 final String subField = extractSubField (singularExpression .field );
6469 if (!subField .isEmpty ()) {
6570 final SingularExpression subExpression =
6671 new SingularExpression (subField , singularExpression .operator , singularExpression .value );
6772 predicates .addAll (
68- getPredicates (cb ,
73+ getPredicates (query , cb ,
6974 reuseOrCreateJoin ((From <?, ?>) from , attribute , field ),
7075 extractSubFieldType (attribute ),
7176 singletonList (subExpression )
@@ -77,7 +82,7 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
7782
7883 Path exprPath = from .get ((SingularAttribute ) attribute );
7984
80- if (Attribute . PersistentAttributeType .EMBEDDED == attribute .getPersistentAttributeType ()) {
85+ if (PersistentAttributeType .EMBEDDED == attribute .getPersistentAttributeType ()) {
8186 final String subField = extractSubField (singularExpression .field );
8287 attribute = extractSubFieldType (attribute ).getAttribute (subField );
8388 exprPath = exprPath .get ((SingularAttribute ) attribute );
@@ -114,7 +119,7 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
114119 predicate = cb .greaterThan (exprPath , (Comparable ) attributeValue );
115120 } else {
116121 throw new IllegalArgumentException ("field should be Number or Comparable: " +
117- singularExpression );
122+ singularExpression );
118123 }
119124 break ;
120125 case $gte :
@@ -124,7 +129,7 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
124129 predicate = cb .greaterThanOrEqualTo (exprPath , (Comparable ) attributeValue );
125130 } else {
126131 throw new IllegalArgumentException ("field should be Number or Comparable: " +
127- singularExpression );
132+ singularExpression );
128133 }
129134 break ;
130135 case $lt :
@@ -134,7 +139,7 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
134139 predicate = cb .lessThan (exprPath , (Comparable ) attributeValue );
135140 } else {
136141 throw new IllegalArgumentException ("field should be Number or Comparable: " +
137- singularExpression );
142+ singularExpression );
138143 }
139144 break ;
140145 case $lte :
@@ -144,7 +149,7 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
144149 predicate = cb .lessThanOrEqualTo (exprPath , (Comparable ) attributeValue );
145150 } else {
146151 throw new IllegalArgumentException ("field should be Number or Comparable: " +
147- singularExpression );
152+ singularExpression );
148153 }
149154 break ;
150155 // like
@@ -179,12 +184,16 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
179184 Attribute <?, ?> attribute = getAttribute (type , field );
180185
181186 if (attribute .isAssociation ()) {
187+ if (attribute instanceof PluralAttribute ) {
188+ query .distinct (true );
189+ }
190+
182191 final String subField = extractSubField (listExpression .field );
183192 if (!subField .isEmpty ()) {
184193 final ListExpression subExpression =
185194 new ListExpression (subField , listExpression .operator , listExpression .values );
186195 predicates .addAll (
187- getPredicates (cb ,
196+ getPredicates (query , cb ,
188197 reuseOrCreateJoin ((From <?, ?>) from , attribute , field ),
189198 extractSubFieldType (attribute ),
190199 singletonList (subExpression )
@@ -196,7 +205,7 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
196205
197206 Path exprPath = from .get ((SingularAttribute ) attribute );
198207
199- if (Attribute . PersistentAttributeType .EMBEDDED == attribute .getPersistentAttributeType ()) {
208+ if (PersistentAttributeType .EMBEDDED == attribute .getPersistentAttributeType ()) {
200209 final String subField = extractSubField (listExpression .field );
201210 attribute = extractSubFieldType (attribute ).getAttribute (subField );
202211 exprPath = exprPath .get ((SingularAttribute ) attribute );
@@ -227,13 +236,13 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
227236
228237 } else if (expression instanceof OrExpression ) {
229238 predicates .add (cb .or (
230- getPredicates (cb , from , type ,
239+ getPredicates (query , cb , from , type ,
231240 ((OrExpression ) expression ).expressions ).toArray (new Predicate [0 ])
232241 ));
233242
234243 } else if (expression instanceof AndExpression ) {
235244 predicates .add (cb .and (
236- getPredicates (cb , from , type ,
245+ getPredicates (query , cb , from , type ,
237246 ((AndExpression ) expression ).expressions ).toArray (new Predicate [0 ])
238247 ));
239248 }
@@ -249,7 +258,7 @@ private static List<Predicate> getPredicates(CriteriaBuilder cb,
249258 throw new IllegalArgumentException (
250259 String .format (
251260 "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?" ,
253262 field ,
254263 type .getJavaType ().getName ()
255264 )
0 commit comments