How to use projections and specifications with spring data jpa?

前端 未结 6 528
执念已碎
执念已碎 2020-12-13 14:53

I\'m not able to use Spring Data JPA projections and specifications together. I have the following setup:

Entity:

@Entity
public cla         


        
相关标签:
6条回答
  • 2020-12-13 15:09

    There is no solution unless you implement you own repository.

    0 讨论(0)
  • 2020-12-13 15:12

    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);
    
    0 讨论(0)
  • 2020-12-13 15:13

    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!

    0 讨论(0)
  • 2020-12-13 15:29

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

    0 讨论(0)
  • 2020-12-13 15:29

    @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

    0 讨论(0)
  • 2020-12-13 15:36

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

    CountryRepository cRepository;
    
    cRepository.findAll(Specification<Country> specification);
    
    0 讨论(0)
提交回复
热议问题