Skip to content
This repository was archived by the owner on Nov 23, 2021. It is now read-only.

Commit 14de69f

Browse files
committed
#627: deprecated custom paging support for the sake of spring-data
1 parent 7bd211f commit 14de69f

File tree

33 files changed

+529
-579
lines changed

33 files changed

+529
-579
lines changed

bom/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,11 @@
356356
<artifactId>oasp4j-jpa</artifactId>
357357
<version>${project.version}</version>
358358
</dependency>
359+
<dependency>
360+
<groupId>io.oasp.java.modules</groupId>
361+
<artifactId>oasp4j-jpa-basic</artifactId>
362+
<version>${project.version}</version>
363+
</dependency>
359364
<dependency>
360365
<groupId>io.oasp.java.modules</groupId>
361366
<artifactId>oasp4j-jpa-envers</artifactId>

modules/jpa/src/main/java/io/oasp/module/jpa/dataaccess/api/QueryDslHelper.java renamed to modules/jpa-basic/src/main/java/io/oasp/module/jpa/dataaccess/api/QueryHelper.java

Lines changed: 83 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@
66
import java.util.Locale;
77

88
import net.sf.mmm.util.exception.api.IllegalCaseException;
9-
import net.sf.mmm.util.search.base.AbstractSearchCriteria;
109

1110
import org.slf4j.Logger;
1211
import org.slf4j.LoggerFactory;
12+
import org.springframework.data.domain.Page;
13+
import org.springframework.data.domain.PageImpl;
14+
import org.springframework.data.domain.Pageable;
15+
import org.springframework.data.domain.Sort;
16+
import org.springframework.data.domain.Sort.Direction;
17+
import org.springframework.data.domain.Sort.Order;
1318
import org.springframework.util.StringUtils;
1419

1520
import com.querydsl.core.JoinExpression;
@@ -26,181 +31,19 @@
2631
import io.oasp.module.basic.common.api.query.LikePatternSyntax;
2732
import io.oasp.module.basic.common.api.query.StringSearchConfigTo;
2833
import io.oasp.module.basic.common.api.query.StringSearchOperator;
29-
import io.oasp.module.jpa.common.api.to.OrderByTo;
30-
import io.oasp.module.jpa.common.api.to.OrderDirection;
31-
import io.oasp.module.jpa.common.api.to.PaginatedListTo;
32-
import io.oasp.module.jpa.common.api.to.PaginationResultTo;
33-
import io.oasp.module.jpa.common.api.to.PaginationTo;
34-
import io.oasp.module.jpa.common.api.to.SearchCriteriaTo;
3534

3635
/**
37-
* Class with utility methods for dealing with QueryDSL. Either extend this class or use {@link QueryDslUtil#get()}.
36+
* Class with utility methods for dealing with queries. Either extend this class or use {@link QueryUtil#get()}.
3837
*
3938
* @since 3.0.0
4039
*/
41-
public class QueryDslHelper {
40+
public class QueryHelper {
4241

43-
private static final Logger LOG = LoggerFactory.getLogger(QueryDslHelper.class);
42+
private static final Logger LOG = LoggerFactory.getLogger(QueryHelper.class);
4443

4544
/** JPA query property to configure the timeout in milliseconds. */
4645
protected static final String QUERY_PROPERTY_TIMEOUT = "javax.persistence.query.timeout";
4746

48-
/**
49-
* Returns a paginated list of entities according to the supplied {@link SearchCriteriaTo criteria}.
50-
* <p>
51-
* Applies {@code limit} and {@code offset} values to the supplied {@code query} according to the supplied
52-
* {@link PaginationTo pagination} information inside {@code criteria}.
53-
* <p>
54-
* If a {@link PaginationTo#isTotal() total count} of available entities is requested, will also execute a second
55-
* query, without pagination parameters applied, to obtain said count.
56-
* <p>
57-
* Will install a query timeout if {@link SearchCriteriaTo#getSearchTimeout()} is not null.
58-
*
59-
* @param <E> generic type of the entity.
60-
* @param criteria contains information about the requested page.
61-
* @param query is a query which is preconfigured with the desired conditions for the search.
62-
* @param applySortOrder - {@code true} to automatically {@link #applySortOrder(List, JPAQuery) apply} the
63-
* {@link SearchCriteriaTo#getSort() sort order} from the given {@link SearchCriteriaTo}, {@code false}
64-
* otherwise (to apply manually for complex queries).
65-
* @return a paginated list.
66-
*/
67-
protected <E> PaginatedListTo<E> findPaginatedGeneric(SearchCriteriaTo criteria, JPAQuery<E> query,
68-
boolean applySortOrder) {
69-
70-
applyTimeout(query, criteria.getSearchTimeout());
71-
72-
PaginationTo pagination = criteria.getPagination();
73-
PaginationResultTo paginationResult = createPaginationResult(pagination, query);
74-
applyPagination(pagination, query);
75-
76-
if (applySortOrder) {
77-
applySortOrder(criteria.getSort(), query);
78-
}
79-
80-
List<E> paginatedList = query.fetch();
81-
82-
return new PaginatedListTo<>(paginatedList, paginationResult);
83-
}
84-
85-
/**
86-
* @param sort the {@link SearchCriteriaTo#getSort() sort order}.
87-
* @param query the {@link JPAQuery} to modify.
88-
*/
89-
@SuppressWarnings("rawtypes")
90-
protected void applySortOrder(List<OrderByTo> sort, JPAQuery<?> query) {
91-
92-
if ((sort == null) || sort.isEmpty()) {
93-
return;
94-
}
95-
PathBuilder<?> alias = findAlias(query);
96-
for (OrderByTo orderBy : sort) {
97-
String name = orderBy.getName();
98-
ComparablePath<Comparable> path = alias.getComparable(name, Comparable.class);
99-
OrderSpecifier<Comparable> orderSpecifier;
100-
if (orderBy.getDirection() == OrderDirection.ASC) {
101-
orderSpecifier = path.asc();
102-
} else {
103-
orderSpecifier = path.desc();
104-
}
105-
query.orderBy(orderSpecifier);
106-
}
107-
}
108-
109-
private <E> PathBuilder<E> findAlias(JPAQuery<E> query) {
110-
111-
String alias = null;
112-
List<JoinExpression> joins = query.getMetadata().getJoins();
113-
if ((joins != null) && !joins.isEmpty()) {
114-
JoinExpression join = joins.get(0);
115-
Expression<?> target = join.getTarget();
116-
if (target instanceof EntityPath) {
117-
alias = target.toString(); // no safe API
118-
}
119-
}
120-
Class<E> type = query.getType();
121-
if (alias == null) {
122-
// should actually never happen, but fallback is provided as buest guess
123-
alias = StringUtils.uncapitalize(type.getSimpleName());
124-
}
125-
return new PathBuilder<>(type, alias);
126-
}
127-
128-
/**
129-
* Creates a {@link PaginationResultTo pagination result} for the given {@code pagination} and {@code query}.
130-
* <p>
131-
* Needs to be called before pagination is applied to the {@code query}.
132-
*
133-
* @param pagination contains information about the requested page.
134-
* @param query is a query preconfigured with the desired conditions for the search.
135-
* @return information about the applied pagination.
136-
*/
137-
protected PaginationResultTo createPaginationResult(PaginationTo pagination, JPAQuery<?> query) {
138-
139-
Long total = calculateTotalBeforePagination(pagination, query);
140-
return new PaginationResultTo(pagination, total);
141-
}
142-
143-
/**
144-
* Calculates the total number of entities the given {@link JPAQuery query} would return without pagination applied.
145-
* <p>
146-
* Needs to be called before pagination is applied to the {@code query}.
147-
*
148-
* @param pagination is the pagination information as requested by the client.
149-
* @param query is the {@link JPAQuery query} for which to calculate the total.
150-
* @return the total count, or {@literal null} if {@link PaginationTo#isTotal()} is {@literal false}.
151-
*/
152-
protected Long calculateTotalBeforePagination(PaginationTo pagination, JPAQuery<?> query) {
153-
154-
Long total = null;
155-
if (pagination.isTotal()) {
156-
total = query.clone().fetchCount();
157-
}
158-
return total;
159-
}
160-
161-
/**
162-
* Applies the {@link PaginationTo pagination criteria} to the given {@link JPAQuery}.
163-
*
164-
* @param pagination is the {@link PaginationTo pagination criteria} to apply.
165-
* @param query is the {@link JPAQuery} to apply to.
166-
*/
167-
protected void applyPagination(PaginationTo pagination, JPAQuery<?> query) {
168-
169-
if (pagination == PaginationTo.NO_PAGINATION) {
170-
return;
171-
}
172-
173-
Integer limit = pagination.getSize();
174-
if (limit != null) {
175-
query.limit(limit);
176-
177-
int page = pagination.getPage();
178-
if (page > 0) {
179-
query.offset((page - 1) * limit);
180-
}
181-
}
182-
}
183-
184-
/**
185-
* Applies the meta-data of the given {@link AbstractSearchCriteria search criteria} to the given {@link JPAQuery}.
186-
*
187-
* @param criteria is the {@link AbstractSearchCriteria search criteria} to apply.
188-
* @param query is the {@link JPAQuery} to apply to.
189-
*/
190-
protected void applyCriteria(AbstractSearchCriteria criteria, JPAQuery<?> query) {
191-
192-
Integer limit = criteria.getMaximumHitCount();
193-
if (limit != null) {
194-
query.limit(limit);
195-
}
196-
int offset = criteria.getHitOffset();
197-
if (offset > 0) {
198-
query.offset(offset);
199-
}
200-
Long timeout = criteria.getSearchTimeout();
201-
applyTimeout(query, timeout);
202-
}
203-
20447
/**
20548
* @param query the {@link JPAQuery} to modify.
20649
* @param timeout the timeout in milliseconds.
@@ -509,4 +352,78 @@ protected <T> void whereIn(JPAQuery<?> query, SimpleExpression<T> expression, Co
509352
}
510353
}
511354

355+
/**
356+
* Returns a {@link Page} of entities according to the supplied {@link Pageable} and {@link JPAQuery}.
357+
*
358+
* @param <E> generic type of the entity.
359+
* @param pageable contains information about the requested page and sorting.
360+
* @param query is a query which is pre-configured with the desired conditions for the search.
361+
* @param determineTotal - {@code true} to determine the {@link Page#getTotalElements() total number of hits},
362+
* {@code false} otherwise.
363+
* @return a paginated list.
364+
*/
365+
protected <E> Page<E> findPaginatedGeneric(Pageable pageable, JPAQuery<E> query, boolean determineTotal) {
366+
367+
long total = -1;
368+
if (determineTotal) {
369+
total = query.clone().fetchCount();
370+
}
371+
int offset = 0;
372+
if (pageable != null) {
373+
offset = pageable.getOffset();
374+
query.offset(offset);
375+
query.limit(pageable.getPageSize());
376+
applySort(query, pageable.getSort());
377+
}
378+
List<E> hits = query.fetch();
379+
if (total == -1) {
380+
total = offset + hits.size();
381+
}
382+
return new PageImpl<>(hits, pageable, total);
383+
}
384+
385+
/**
386+
* @param query the {@link JPAQuery} to apply the {@link Sort} to.
387+
* @param sort the {@link Sort} to apply as ORDER BY to the given {@link JPAQuery}.
388+
*/
389+
@SuppressWarnings("rawtypes")
390+
protected void applySort(JPAQuery<?> query, Sort sort) {
391+
392+
if (sort == null) {
393+
return;
394+
}
395+
PathBuilder<?> alias = findAlias(query);
396+
for (Order order : sort) {
397+
String property = order.getProperty();
398+
Direction direction = order.getDirection();
399+
ComparablePath<Comparable> path = alias.getComparable(property, Comparable.class);
400+
OrderSpecifier<Comparable> orderSpecifier;
401+
if (direction == Direction.ASC) {
402+
orderSpecifier = path.asc();
403+
} else {
404+
orderSpecifier = path.desc();
405+
}
406+
query.orderBy(orderSpecifier);
407+
}
408+
}
409+
410+
private <E> PathBuilder<E> findAlias(JPAQuery<E> query) {
411+
412+
String alias = null;
413+
List<JoinExpression> joins = query.getMetadata().getJoins();
414+
if ((joins != null) && !joins.isEmpty()) {
415+
JoinExpression join = joins.get(0);
416+
Expression<?> target = join.getTarget();
417+
if (target instanceof EntityPath) {
418+
alias = target.toString(); // no safe API
419+
}
420+
}
421+
Class<E> type = query.getType();
422+
if (alias == null) {
423+
// should actually never happen, but fallback is provided as buest guess
424+
alias = StringUtils.uncapitalize(type.getSimpleName());
425+
}
426+
return new PathBuilder<>(type, alias);
427+
}
428+
512429
}

modules/jpa/src/main/java/io/oasp/module/jpa/dataaccess/api/QueryDslUtil.java renamed to modules/jpa-basic/src/main/java/io/oasp/module/jpa/dataaccess/api/QueryUtil.java

Lines changed: 23 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package io.oasp.module.jpa.dataaccess.api;
22

33
import java.util.Collection;
4-
import java.util.List;
4+
5+
import org.springframework.data.domain.Page;
6+
import org.springframework.data.domain.Pageable;
57

68
import com.querydsl.core.types.dsl.BooleanExpression;
79
import com.querydsl.core.types.dsl.SimpleExpression;
@@ -11,55 +13,15 @@
1113
import io.oasp.module.basic.common.api.query.LikePatternSyntax;
1214
import io.oasp.module.basic.common.api.query.StringSearchConfigTo;
1315
import io.oasp.module.basic.common.api.query.StringSearchOperator;
14-
import io.oasp.module.jpa.common.api.to.PaginatedListTo;
15-
import io.oasp.module.jpa.common.api.to.PaginationTo;
16-
import io.oasp.module.jpa.common.api.to.SearchCriteriaTo;
1716

1817
/**
19-
* Helper class for generic handling of {@link net.sf.mmm.util.entity.api.PersistenceEntity persistence entities} (based
20-
* on {@link javax.persistence.EntityManager}).
18+
* Helper class for {@link #get() static access} to features of {@link QueryHelper}.
2119
*
2220
* @since 3.0.0
2321
*/
24-
public class QueryDslUtil extends QueryDslHelper {
25-
26-
private static final QueryDslUtil INSTANCE = new QueryDslUtil();
27-
28-
/**
29-
* @param <E> generic type of the entity.
30-
* @param criteria contains information about the requested page.
31-
* @param query is a query which is preconfigured with the desired conditions for the search including search order.
32-
* @return a paginated list.
33-
* @see #findPaginated(SearchCriteriaTo, JPAQuery, boolean)
34-
*/
35-
public <E> PaginatedListTo<E> findPaginated(SearchCriteriaTo criteria, JPAQuery<E> query) {
36-
37-
return findPaginatedGeneric(criteria, query, true);
38-
}
39-
40-
/**
41-
* Returns a paginated list of entities according to the supplied {@link SearchCriteriaTo criteria}.
42-
* <p>
43-
* Applies {@code limit} and {@code offset} values to the supplied {@code query} according to the supplied
44-
* {@link PaginationTo pagination} information inside {@code criteria}.
45-
* <p>
46-
* If a {@link PaginationTo#isTotal() total count} of available entities is requested, will also execute a second
47-
* query, without pagination parameters applied, to obtain said count.
48-
* <p>
49-
* Will install a query timeout if {@link SearchCriteriaTo#getSearchTimeout()} is not null.
50-
*
51-
* @param <E> generic type of the entity.
52-
* @param criteria contains information about the requested page.
53-
* @param query is a query which is preconfigured with the desired conditions for the search.
54-
* @param applySortOrder - {@code true} to automatically {@link #applySortOrder(List, JPAQuery) apply} the
55-
* {@link SearchCriteriaTo#getSort() sort order} from the given {@link SearchCriteriaTo}, {@code false}
56-
* otherwise (to apply manually for complex queries).
57-
* @return a paginated list.
58-
*/
59-
public <E> PaginatedListTo<E> findPaginated(SearchCriteriaTo criteria, JPAQuery<E> query, boolean applySortOrder) {
22+
public class QueryUtil extends QueryHelper {
6023

61-
return findPaginatedGeneric(criteria, query, true);
62-
}
24+
private static final QueryUtil INSTANCE = new QueryUtil();
6325

6426
@Override
6527
public void whereLike(JPAQuery<?> query, StringExpression expression, String pattern, LikePatternSyntax syntax,
@@ -128,9 +90,24 @@ public <T> void whereIn(JPAQuery<?> query, SimpleExpression<T> expression, Colle
12890
}
12991

13092
/**
131-
* @return the {@link QueryDslUtil} instance.
93+
* Returns a {@link Page} of entities according to the supplied {@link Pageable} and {@link JPAQuery}.
94+
*
95+
* @param <E> generic type of the entity.
96+
* @param pageable contains information about the requested page and sorting.
97+
* @param query is a query which is pre-configured with the desired conditions for the search.
98+
* @param determineTotal - {@code true} to determine the {@link Page#getTotalElements() total number of hits},
99+
* {@code false} otherwise.
100+
* @return a paginated list.
101+
*/
102+
public <E> Page<E> findPaginated(Pageable pageable, JPAQuery<E> query, boolean determineTotal) {
103+
104+
return findPaginatedGeneric(pageable, query, determineTotal);
105+
}
106+
107+
/**
108+
* @return the {@link QueryUtil} instance.
132109
*/
133-
public static QueryDslUtil get() {
110+
public static QueryUtil get() {
134111

135112
return INSTANCE;
136113
}

0 commit comments

Comments
 (0)