Let\'s say I have a data model like this (pseudocode):
@Entity
Person {
@OneToMany
List attributes;
}
@Entity
PersonAttribute {
In order to perform more complex queries I've created my custom QueryDslRepository
with support of JPQL queries and spring data JPA pagination.
Interface:
public interface QueryDslRepository {
Page findAll(JPQLQuery jpqlQuery, Pageable pageable);
}
Implementation:
@Repository
public class QueryDslRepositoryImpl implements QueryDslRepository {
@PersistenceContext
private EntityManager entityManager;
@Override
@SuppressWarnings("unchecked")
public Page findAll(JPQLQuery jpqlQuery, Pageable pageable) {
Assert.notNull(jpqlQuery, "JPQLQuery must not be null!");
Assert.notNull(pageable, "Pageable must not be null!");
Querydsl querydsl = new Querydsl(entityManager, new PathBuilderFactory()
.create(jpqlQuery.getType()));
JPQLQuery countQuery = ((AbstractJPAQuery) jpqlQuery).clone(entityManager);
AbstractJPAQuery query = (AbstractJPAQuery) querydsl.applyPagination(pageable, jpqlQuery);
return PageableExecutionUtils.getPage(
// Clone query in order to provide entity manager instance.
query.clone(entityManager).fetch(),
pageable,
countQuery::fetchCount);
}
}
Example of use:
@Repository
public interface CustomerRepository extends JpaRepository, QueryDslRepository,
QuerydslPredicateExecutor {
}
Actual repository invocation:
BooleanBuilder predicates = new BooleanBuilder();
predicates = predicates.and(QCustomer.customer.active.eq(true));
JPQLQuery q = new JPAQuery()
.select(QCustomer.customer)
// You can use .join() method here.
.where(predicates);
Page result = customerRepository.findAll(q, Pageable.unpaged());