How to use projections and specifications with spring data jpa?

我们两清 提交于 2019-12-02 19:42:14
mpprdev

The ability to mix Projections and Specifications are not yet supported. There is a bug tracking this.

I found this https://github.com/pramoth/specification-with-projection and it seems to work which does exactly what you're looking for. I've included it in my own project and so far no problems. Big thanks to Pramoth.

Basically you extend JpaSpecificationExecutorWithProjection instead of JpaSpecificationExecutor.

public interface DocumentRepository extends JpaRepository< Country,Long>,JpaSpecificationExecutorWithProjection<Country,Long>

and you get findall() method with projections and specifications

<R> Page<R> findAll(Specification<T> spec, Class<R> projectionClass, Pageable pageable);

There is no solution unless you implement you own repository.

Rhett

If you use Specification, you can't use in CountryRepository.

CountryRepository cRepository;

cRepository.findAll(Specification<Country> specification);

Another way you could solve this is by using the ProxyProjectionFactory. You would have your repository fetch the actual entity and then along the line (maybe in your service layer), map the resultset into the projection type. See below;

public interface CountryRepository extends JpaRepository<Country, Long>, JpaSpecificationExecutor<Country> {  

}

then in your service, you do this;

List<CountryProjection> findAllProjectedBy(Specification<Country> countrySpecification) {
    List<Country> countries = this.countryRepository.findAll(countrySpecification);

    ProxyProjectionFactory pf= new SpelAwareProxyProjectionFactory();
    return countries.stream().map(c->pf.createProjection(CountryProjection.class, c)).collect(Collectors.toList());
}

Hope this helps!

@esdee: For now, I Created a Custom Repository Implementation where I created a dynamic query where you can create even a native query and map it to a DTO without using projections.

In order to do this you can see this doc:

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations

Here is a already example:

Spring Data JPA Custom Repository

Just keep in mind that if you want to make it pageable, in your Custom Repository you have to create also a method to count the rows, that you want to extract in your customFindAll(parameters). The disadgantage is that I rewrote the specifications in native query. But maybe the custom Implmentation can work also with Specification, let me know if it helps.

Regards, C

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!