@@ -345,12 +345,7 @@ protected Predicate getArgumentPredicate(CriteriaBuilder cb, From<?,?> path,
345345 .filter (predicate -> predicate != null )
346346 .forEach (predicates ::add );
347347
348- if (predicates .isEmpty ())
349- predicates .add (cb .disjunction ());
350-
351- return (logical == Logical .OR )
352- ? cb .or (predicates .toArray (new Predicate [predicates .size ()]))
353- : cb .and (predicates .toArray (new Predicate [predicates .size ()]));
348+ return getCompoundPredicate (cb , predicates , logical );
354349 }
355350
356351 private Logical extractLogical (Argument argument ) {
@@ -375,6 +370,7 @@ private Predicate getFieldPredicate(String fieldName, CriteriaBuilder cb, From<?
375370
376371 List <Predicate > predicates = new ArrayList <>();
377372
373+ // Let's parse logical expressions, i.e. AND, OR
378374 expressionValue .getObjectFields ().stream ()
379375 .filter (it -> Logical .names ().contains (it .getName ()))
380376 .map (it -> getFieldPredicate (fieldName , cb , path , it ,
@@ -383,49 +379,55 @@ private Predicate getFieldPredicate(String fieldName, CriteriaBuilder cb, From<?
383379 )
384380 .forEach (predicates ::add );
385381
386- // Let's parse relation criteria expressions if present
387- expressionValue .getObjectFields ().stream ()
388- .filter (it -> !Logical .names ().contains (it .getName ()) && !Criteria .names ().contains (it .getName ()))
389- .map (it -> {
390- GraphQLFieldDefinition fieldDefinition = getFieldDef (environment .getGraphQLSchema (),
391- this .getObjectType (environment , argument ),
392- new Field (fieldName ));
393-
394- Map <String , Object > arguments = new LinkedHashMap <>();
395-
382+ // Let's parse relation criteria expressions if present, i.e. books, author, etc.
383+ if (expressionValue .getObjectFields ()
384+ .stream ()
385+ .anyMatch (it -> !Logical .names ().contains (it .getName ()) && !Criteria .names ().contains (it .getName ())))
386+ {
387+ GraphQLFieldDefinition fieldDefinition = getFieldDef (environment .getGraphQLSchema (),
388+ this .getObjectType (environment , argument ),
389+ new Field (fieldName ));
390+ Map <String , Object > arguments = new LinkedHashMap <>();
391+
392+ if (Logical .names ().contains (argument .getName ()))
393+ arguments .put (logical .name (), environment .getArgument (argument .getName ()));
394+ else
396395 arguments .put (logical .name (), environment .getArgument (fieldName ));
397-
398- return getArgumentPredicate (cb , reuseJoin (path , fieldName , false ),
399- wherePredicateEnvironment (environment , fieldDefinition , arguments ),
400- new Argument (logical .name (), expressionValue ));
401- }
402- )
403- .forEach (predicates ::add );
404-
405- Optional <Predicate > relationPredicate = predicates .stream ().findFirst ();
406-
407- // Let's check if relation criteria predicate exists, to avoid adding duplicate predicates in the query
408- if (relationPredicate .isPresent ()) {
409- return relationPredicate .get ();
396+
397+ return getArgumentPredicate (cb , reuseJoin (path , fieldName , false ),
398+ wherePredicateEnvironment (environment , fieldDefinition , arguments ),
399+ new Argument (logical .name (), expressionValue ));
410400 }
411401
402+ // Let's parse simple Criteria expressions, i.e. EQ, LIKE, etc.
412403 JpaPredicateBuilder pb = new JpaPredicateBuilder (cb , EnumSet .of (Logical .AND ));
413404
414- expressionValue .getObjectFields ().stream ()
405+ expressionValue .getObjectFields ()
406+ .stream ()
415407 .filter (it -> Criteria .names ().contains (it .getName ()))
416408 .map (it -> getPredicateFilter (new ObjectField (fieldName , it .getValue ()),
417- argumentEnvironment (environment , argument .getName ()),
418- new Argument (it .getName (), it .getValue ()))
419- )
409+ argumentEnvironment (environment , argument .getName ()),
410+ new Argument (it .getName (), it .getValue ())))
420411 .sorted ()
421412 .map (it -> pb .getPredicate (path , path .get (it .getField ()), it ))
422413 .filter (predicate -> predicate != null )
423414 .forEach (predicates ::add );
424415
425- return (logical == Logical .OR )
426- ? cb .or (predicates .toArray (new Predicate [predicates .size ()]))
427- : cb .and (predicates .toArray (new Predicate [predicates .size ()]));
416+ return getCompoundPredicate (cb , predicates , logical );
428417
418+ }
419+
420+ private Predicate getCompoundPredicate (CriteriaBuilder cb , List <Predicate > predicates , Logical logical ) {
421+ if (predicates .isEmpty ())
422+ return cb .disjunction ();
423+
424+ if (predicates .size () == 1 ) {
425+ return predicates .get (0 );
426+ }
427+
428+ return (logical == Logical .OR )
429+ ? cb .or (predicates .toArray (new Predicate [predicates .size ()]))
430+ : cb .and (predicates .toArray (new Predicate [predicates .size ()]));
429431 }
430432
431433 private PredicateFilter getPredicateFilter (ObjectField objectField , DataFetchingEnvironment environment , Argument argument ) {
0 commit comments