4

I saw the Selecting from Multiple Tables in Spring Data already had the solution for multiple tables. I would like to know if it is possible to write custom query that has tables with pageable and sorting feature at the same time in Spring JPA/DATA.

SELECT s.service_id, s.name, us.rating_id 
FROM services s, 
   ratings r, 
   user_services us
where 
   us.service_id = s.service_id and
   us.rating_id = r.rating_id and
   us.user_id= ?
;

Thanks for you help in advance.

sunkuet02
  • 2,376
  • 1
  • 26
  • 33
linc01n
  • 418
  • 2
  • 6
  • 17

1 Answers1

15

Sorting feature is under question, but pagination is possible to use.

Assume that we have:

@Entity
public class Service {

    @Id
    private Long id;

    private String name;

    //...
}

@Entity
public class UserService {

    @Id
    private Long id;

    @ManyToOne        
    User user;

    @ManyToOne        
    Service service;   

    @ManyToOne        
    Rating rating;   

    //...
}

Then we create a projection:

public interface ServiceRating {
    Long getServiceId();
    String getServiceName();
    Long getRatingId();
}

And then create a query method supported pagination:

public interface UserServiceRepo extends CrudRepository<UserService, Long> {
    @Query("select s.id as serviceId, s.name as serviceName, us.rating.id as ratingId from UserService us join us.service s where us.user.id = ?1")
    Page<ServiceRating> getServiceRating(Long userId, Pageable pageable);
}

(Since this query does not contain grouping it's not necessary to use an additional countQuery (see the parameter of @Query)).

Test:

Page<ServiceRating> pages = userServiceRepo.getServiceRating(1L, new PageRequest(0, 10));
assertThat(pages.getContent()).hasSize(10));

UPDATE

Sorting also working perfectly. Just create a Sort object, specify direction and filed name (from the projection):

Sort sort = new Sort(Sort.Direction.ASC, "serviceName");
userServiceRepo.getServiceRating(1L, new PageRequest(0, 10, sort));
Cepr0
  • 28,144
  • 8
  • 75
  • 101
  • Thank you @Cepr0! – linc01n Aug 07 '17 at 06:46
  • @linc01n 'Thank you' is equal to 'accepting/upvoting' the answer here. Please don't forget to do it... – Cepr0 Aug 07 '17 at 07:43
  • 1
    Hi, I met a problem: When I create a projection interface and try to run the application, An error: java.lang.IllegalArgumentException: Not a managed type .... – wjxiz Jun 22 '18 at 03:55