52
52
import jakarta .persistence .criteria .Subquery ;
53
53
import jakarta .persistence .metamodel .ManagedType ;
54
54
import java .util .ArrayList ;
55
- import java .util .Arrays ;
56
55
import java .util .Collection ;
57
56
import java .util .Collections ;
58
57
import java .util .HashMap ;
@@ -91,16 +90,16 @@ public <R, P> CriteriaQuery<P> buildQuery(R request, SearchConfiguration<T, P, R
91
90
searchProjectionList = ProjectionListResolverUtil .resolveSearchProjectionList (resultClass );
92
91
}
93
92
94
- List <Selection <?>> projectionList = resolveQueryProjectionList (root , searchProjectionList , request );
93
+ resolveAndApplyPredicateList (request , searchConfiguration , criteriaBuilder , root , query );
94
+
95
+ List <Selection <?>> projectionList = resolveQueryProjectionList (root , searchConfiguration .getDefaultJoinType (), searchProjectionList , request );
95
96
96
97
if (!CollectionUtils .isEmpty (projectionList )) {
97
98
query .multiselect (projectionList );
98
99
}
99
100
100
101
query .distinct (searchConfiguration .isDistinct ());
101
102
102
- resolveAndApplyPredicateList (request , searchConfiguration , criteriaBuilder , root , query );
103
-
104
103
if (sort != null && sort .isSorted ()) {
105
104
query .orderBy (QueryUtils .toOrders (sort , root , criteriaBuilder ));
106
105
}
@@ -193,14 +192,14 @@ private <R> void applyJoinsOrFetchesToQuery(boolean applyFetch, R request, Root<
193
192
.forEach (searchJoin -> applyJoinOrJoinFetch (existingFetches , existingJoins , root , searchJoin , applyFetch ));
194
193
}
195
194
196
- private <R > List <Selection <?>> resolveQueryProjectionList (Root <?> root , List <SearchProjection <R >> projectionList , R request ) {
195
+ private <R > List <Selection <?>> resolveQueryProjectionList (Root <?> root , JoinType defaultJoinType , List <SearchProjection <R >> projectionList , R request ) {
197
196
if (CollectionUtils .isEmpty (projectionList )) {
198
197
return Collections .emptyList ();
199
198
}
200
199
201
200
return projectionList .stream ()
202
201
.filter (projection -> shouldApplyProjection (projection , request ))
203
- .map (projection -> convertToSelectionExpression (root , projection ))
202
+ .map (projection -> convertToSelectionExpression (defaultJoinType , root , projection ))
204
203
.collect (Collectors .toList ());
205
204
}
206
205
@@ -247,21 +246,21 @@ private <P, R> void resolveAndApplyPredicateList(R request, SearchConfiguration<
247
246
}
248
247
249
248
private <P , R > List <Predicate > resolveQueryPredicateList (R request , SearchConfiguration <T , P , R > searchConfiguration , CriteriaBuilder criteriaBuilder , Root <?> root , CriteriaQuery <?> query ) {
249
+ JoinType defaultJoinType = searchConfiguration .getDefaultJoinType ();
250
250
Set <Restriction > restrictionList = new SearchDataParser (root .getModel (), request , SearchDataParserConfiguration .fromSearchConfiguration (searchConfiguration )).resolveRestrictionList ();
251
-
252
251
Map <Boolean , List <Restriction >> restrictionsByType = restrictionList .stream ().collect (Collectors .partitioningBy (Restriction ::isPluralAttribute ));
253
252
254
- List <Predicate > mainQueryPredicateList = convertRestrictionListToPredicateList (restrictionsByType .get (false ), root , criteriaBuilder );
253
+ List <Predicate > mainQueryPredicateList = convertRestrictionListToPredicateList (restrictionsByType .get (false ), root , criteriaBuilder , defaultJoinType );
255
254
256
255
List <Restriction > pluralRestrictionList = restrictionsByType .get (true );
257
256
if (!CollectionUtils .isEmpty (pluralRestrictionList )) {
258
257
259
258
if (searchConfiguration .getPluralAssociationRestrictionType () == PluralAssociationRestrictionType .JOIN ) {
260
- mainQueryPredicateList .addAll (convertRestrictionListToPredicateList (pluralRestrictionList , root , criteriaBuilder ));
259
+ mainQueryPredicateList .addAll (convertRestrictionListToPredicateList (pluralRestrictionList , root , criteriaBuilder , defaultJoinType ));
261
260
}
262
261
else {
263
262
SearchPropertyJoin searchPropertyJoin = resolveSearchPropertyJoin (root );
264
- Subquery <Integer > subquery = createSubqueryRestriction (root .getJavaType (), root , query , criteriaBuilder , pluralRestrictionList , searchPropertyJoin );
263
+ Subquery <Integer > subquery = createSubqueryRestriction (root .getJavaType (), root , query , criteriaBuilder , pluralRestrictionList , searchPropertyJoin , defaultJoinType );
265
264
266
265
mainQueryPredicateList .add (criteriaBuilder .exists (subquery ));
267
266
}
@@ -274,39 +273,34 @@ private <P, R> List<Predicate> resolveQueryPredicateList(R request, SearchConfig
274
273
return mainQueryPredicateList ;
275
274
}
276
275
277
- private Subquery <Integer > createSubqueryRestriction (Class <?> subqueryEntityType , Root <?> parent , CriteriaQuery <?> query , CriteriaBuilder criteriaBuilder , Collection <Restriction > restrictionList , SearchPropertyJoin searchPropertyJoin ) {
276
+ private Subquery <Integer > createSubqueryRestriction (
277
+ Class <?> subqueryEntityType , Root <?> parent , CriteriaQuery <?> query , CriteriaBuilder criteriaBuilder ,
278
+ Collection <Restriction > restrictionList , SearchPropertyJoin searchPropertyJoin , JoinType defaultJoinType
279
+ ) {
278
280
Subquery <Integer > subquery = query .subquery (Integer .class );
279
281
Root <?> subqueryRoot = subquery .from (subqueryEntityType );
280
282
281
283
subquery .select (criteriaBuilder .literal (1 ));
282
284
283
- List <Predicate > subQueryPredicateList = convertRestrictionListToPredicateList (restrictionList , subqueryRoot , criteriaBuilder );
285
+ List <Predicate > subQueryPredicateList = convertRestrictionListToPredicateList (restrictionList , subqueryRoot , criteriaBuilder , defaultJoinType );
284
286
285
- Path <?> parentPath = PathResolvingUtil .calculateFullRestrictionPath (parent , PathResolvingUtil .convertToPathList (searchPropertyJoin .getParentProperty ()));
286
- Path <?> subqueryPath = PathResolvingUtil .calculateFullRestrictionPath (subqueryRoot , PathResolvingUtil .convertToPathList (searchPropertyJoin .getChildProperty ()));
287
+ Path <?> parentPath = PathResolvingUtil .calculateFullPath (parent , defaultJoinType , PathResolvingUtil .convertToPathList (searchPropertyJoin .getParentProperty ()));
288
+ Path <?> subqueryPath = PathResolvingUtil .calculateFullPath (subqueryRoot , defaultJoinType , PathResolvingUtil .convertToPathList (searchPropertyJoin .getChildProperty ()));
287
289
288
290
subQueryPredicateList .add (criteriaBuilder .equal (parentPath , subqueryPath ));
289
291
290
292
return subquery .where (subQueryPredicateList .toArray (new Predicate [0 ]));
291
293
}
292
294
293
- private List <Predicate > convertRestrictionListToPredicateList (Collection <Restriction > restrictionList , Root <?> rootPath , CriteriaBuilder criteriaBuilder ) {
295
+ private List <Predicate > convertRestrictionListToPredicateList (Collection <Restriction > restrictionList , Root <?> rootPath , CriteriaBuilder criteriaBuilder , JoinType joinType ) {
294
296
List <Predicate > predicateList = new ArrayList <>();
295
297
296
298
restrictionList .stream ().filter (Objects ::nonNull ).forEach (restriction -> {
297
299
String [] pathList = PathResolvingUtil .convertToPathList (restriction .getPath ());
298
300
299
- if (restriction .isPluralAttribute ()) {
300
- String [] pluralAttributePathList = Arrays .copyOfRange (pathList , 1 , pathList .length );
301
- Path <?> fullPath = PathResolvingUtil .calculateFullRestrictionPath (rootPath .join (pathList [0 ]), pluralAttributePathList );
301
+ Path <?> fullPath = PathResolvingUtil .calculateFullPath (rootPath , joinType , pathList );
302
302
303
- predicateList .add (restriction .getSearchOperator ().asPredicate (criteriaBuilder , fullPath , restriction .getValue ()));
304
- }
305
- else {
306
- Path <?> fullPath = PathResolvingUtil .calculateFullRestrictionPath (rootPath , pathList );
307
-
308
- predicateList .add (restriction .getSearchOperator ().asPredicate (criteriaBuilder , fullPath , restriction .getValue ()));
309
- }
303
+ predicateList .add (restriction .getSearchOperator ().asPredicate (criteriaBuilder , fullPath , restriction .getValue ()));
310
304
});
311
305
312
306
return predicateList ;
@@ -324,10 +318,15 @@ private <R> List<Subquery<?>> resolveSubqueryList(R request, SearchPropertyConfi
324
318
return Collections .emptyList ();
325
319
}
326
320
327
- return subqueryConfigurationList .stream ().map (subqueryConfiguration -> buildSubquery (request , searchPropertyConfiguration , root , query , criteriaBuilder , subqueryConfiguration )).filter (Objects ::nonNull ).collect (Collectors .toList ());
321
+ return subqueryConfigurationList .stream ()
322
+ .map (subqueryConfiguration -> buildSubquery (request , searchPropertyConfiguration , root , query , criteriaBuilder , subqueryConfiguration ))
323
+ .filter (Objects ::nonNull )
324
+ .collect (Collectors .toList ());
328
325
}
329
326
330
- private <R > Subquery <Integer > buildSubquery (R request , SearchPropertyConfiguration searchPropertyConfiguration , Root <?> root , CriteriaQuery <?> query , CriteriaBuilder criteriaBuilder , SubqueryConfiguration subqueryConfiguration ) {
327
+ private <R > Subquery <Integer > buildSubquery (
328
+ R request , SearchPropertyConfiguration searchPropertyConfiguration , Root <?> root , CriteriaQuery <?> query , CriteriaBuilder criteriaBuilder , SubqueryConfiguration subqueryConfiguration
329
+ ) {
331
330
ManagedType <?> subqueryRoot = entityManager .getMetamodel ().managedType (subqueryConfiguration .getRootEntity ());
332
331
333
332
Set <Restriction > subqueryRestrictionList ;
@@ -346,16 +345,18 @@ private <R> Subquery<Integer> buildSubquery(R request, SearchPropertyConfigurati
346
345
347
346
Subquery <Integer > subquery = null ;
348
347
if (!CollectionUtils .isEmpty (subqueryRestrictionList )) {
349
- subquery = createSubqueryRestriction (subqueryConfiguration .getRootEntity (), root , query , criteriaBuilder , subqueryRestrictionList , subqueryConfiguration .getJoinBy ());
348
+ subquery = createSubqueryRestriction (
349
+ subqueryConfiguration .getRootEntity (), root , query , criteriaBuilder , subqueryRestrictionList , subqueryConfiguration .getJoinBy (), subqueryConfiguration .getDefaultJoinType ()
350
+ );
350
351
}
351
352
352
353
return subquery ;
353
354
}
354
355
355
- private <R > Selection <?> convertToSelectionExpression (Path <?> root , SearchProjection <R > projection ) {
356
+ private <R > Selection <?> convertToSelectionExpression (JoinType defaultJoinType , Root <?> root , SearchProjection <R > projection ) {
356
357
String [] pathList = PathResolvingUtil .convertToPathList (projection .getPath ());
357
358
358
- Path <?> path = PathResolvingUtil .calculateFullSelectionPath (root , pathList );
359
+ Path <?> path = PathResolvingUtil .calculateFullPath (root , defaultJoinType , pathList );
359
360
360
361
String alias = projection .getAlias () == null ? pathList [pathList .length - 1 ] : projection .getAlias ();
361
362
0 commit comments