package com.thinkbiganalytics.metadata.jpa.support; /*- * #%L * thinkbig-operational-metadata-jpa * %% * Copyright (C) 2017 ThinkBig Analytics * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import com.querydsl.core.types.Predicate; import com.querydsl.core.types.dsl.EntityPathBase; import com.querydsl.jpa.JPQLQuery; import com.querydsl.jpa.impl.JPAQuery; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.support.QueryDslRepositorySupport; import org.springframework.data.querydsl.QPageRequest; import java.util.Collections; import java.util.List; /** * Spring data provides out of the box capability to get paging results via a direct JPA object, but doesn't expose it for JPA queries. This class allows a provider to get page results from a QueryDSL * JPAQuery */ public class QueryDslPagingSupport<E> extends QueryDslRepositorySupport { public QueryDslPagingSupport(Class<E> clazz) { super(clazz); } protected Page<E> findAll(JPAQuery query, Pageable pageable) { if (pageable == null) { pageable = new QPageRequest(0, Integer.MAX_VALUE); } long total = query.clone(super.getEntityManager()).fetchCount(); JPQLQuery pagedQuery = getQuerydsl().applyPagination(pageable, query); List<E> content = total > pageable.getOffset() ? pagedQuery.fetch() : Collections.<E>emptyList(); return new PageImpl<>(content, pageable, total); } public Page<E> findAllWithFetch(EntityPathBase<E> path, Predicate predicate, Pageable pageable, QueryDslFetchJoin... joins) { if (pageable == null) { pageable = new QPageRequest(0, Integer.MAX_VALUE); } long total = createFetchCountQuery(path, predicate).fetchCount(); JPQLQuery pagedQuery = getQuerydsl().applyPagination(pageable, createFetchQuery(path, predicate, joins)); List<E> content = total > pageable.getOffset() ? pagedQuery.fetch() : Collections.<E>emptyList(); return new PageImpl<>(content, pageable, total); } private JPQLQuery createFetchCountQuery(EntityPathBase<E> path, Predicate predicate) { JPQLQuery query = from(path); query.where(predicate); return query; } private JPQLQuery createFetchQuery(EntityPathBase<E> path, Predicate predicate, QueryDslFetchJoin... joins) { JPQLQuery query = from(path); for (QueryDslFetchJoin joinDescriptor : joins) { join(joinDescriptor, query); } query.where(predicate); return query; } private JPQLQuery join(QueryDslFetchJoin join, JPQLQuery query) { switch (join.type) { case INNER: query.innerJoin(join.joinPath).fetchJoin(); break; case JOIN: query.join(join.joinPath).fetchJoin(); break; case LEFT: query.leftJoin(join.joinPath).fetchJoin(); break; case RIGHT: query.rightJoin(join.joinPath).fetchJoin(); break; case INNER_ALIAS: query.innerJoin(join.joinPath, join.alias).fetchJoin(); break; case JOIN_ALIAS: query.join(join.joinPath, join.alias).fetchJoin(); break; case LEFT_ALIAS: query.leftJoin(join.joinPath, join.alias).fetchJoin(); break; case RIGHT_ALIAS: query.rightJoin(join.joinPath, join.alias).fetchJoin(); break; } return query; } }