spring-projects / spring-data-commons

Spring Data Commons. Interfaces and code shared between the various datastore specific implementations.
https://spring.io/projects/spring-data
Apache License 2.0
778 stars 675 forks source link

Improve Querydsl support in custom repositories [DATACMNS-898] #1356

Open spring-projects-issues opened 8 years ago

spring-projects-issues commented 8 years ago

Andrei Ivanov opened DATACMNS-898 and commented

Hi, As far as I understand from the documentation, working with Querydsl in a repository means that the repository interface should extend QueryDslPredicateExecutor:

public interface SiteAccessRequestsRepository extends PagingAndSortingRepository<SiteAccessRequest, Long>, QueryDslPredicateExecutor<SiteAccessRequest> {
}

This seems a bit weird to me because now the "query" gets created in the service/facade layer:

import com.example.siteaccess.dao.expressions.SiteAccessRequestExpressions;
@Service
public class SiteAccessRequestsFacadeImpl implements SiteAccessRequestsFacade {

    @Override
    public Page<SiteAccessRequest> getSiteAccessRequests(SiteAccessRequest probe, Pageable pageable) throws BusinessException {
        Predicate predicate = SiteAccessRequestExpressions.byExample(probe);
        return siteAccessRequestsRepository.findAll(predicate, pageable);
    }
}

And this also make integration testing difficult, as this is similar to having a method like findAll(String sql) defined in the repository interface.

So I tried to create a custom repository for this:

interface SiteAccessRequestsRepositoryCustom {
    Page<SiteAccessRequest> findByExample(SiteAccessRequest probe, Pageable pageable);
}

public class SiteAccessRequestsRepositoryImpl extends QueryDslRepositorySupport implements SiteAccessRequestsRepositoryCustom {

    public SiteAccessRequestsRepositoryImpl() {
        super(SiteAccessRequest.class);
    }

    @Override
    public Page<SiteAccessRequest> findByExample(SiteAccessRequest criteria, Pageable pageable) {
        Predicate predicate = SiteAccessRequestExpressions.byExample(criteria);
        //JPQLQuery<?> countQuery = createQuery(predicate);

        return null;
    }
}

This is were I got stuck. When using the QueryDslPredicateExecutor, the findAll(Predicate predicate, Pageable pageable) method is handled by QueryDslJpaRepository. But QueryDslRepositorySupport has only some basic methods to perform queries. What I am suggesting is to move some of the methods from QueryDslJpaRepository to QueryDslPredicateExecutor to make this case easier to implement.

Or maybe there already is a better way to implement custom repositories with Querydsl that I haven't seen?


Affects: 1.12.2 (Hopper SR2)

spring-projects-issues commented 8 years ago

Oliver Drotbohm commented

What exactly are you missing in QueryDslRepositorySupport? It basically allows you to call from(SiteAccessRequest.class).where( SiteAccessRequestExpressions.byExample(criteria))… and by that move that logic into the repository layer if desired

spring-projects-issues commented 8 years ago

Andrei Ivanov commented

Well, at least QueryDslJpaRepository.findAll(Predicate predicate, Pageable pageable) content I would have to copy/paste in my own method. Then from(SiteAccessRequest.class) doesn't seem to work, as QueryDslRepositorySupport.from expects an EntityPath (I see these are created in the constructor of QueryDslJpaRepository)

spring-projects-issues commented 8 years ago

Oliver Drotbohm commented

My mistake, I am not near any IDE right now. I guess it expects a Querydsl root path then. Something from the meta-model it generates, like QUser.user or the like.

So it boils down to the lack of application of Pageable?

spring-projects-issues commented 8 years ago

Andrei Ivanov commented

At least for what I'm doing now, I think so. Even for a simple query I think it would be nice to get an example in the documentation about this combination of custom repository and Querydsl

spring-projects-issues commented 3 years ago

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.