spring-data-jpa icon indicating copy to clipboard operation
spring-data-jpa copied to clipboard

Repository returns PageImpl and executes count query when using Slice as return type [DATAJPA-1464]

Open spring-projects-issues opened this issue 6 years ago • 8 comments
trafficstars

Martin Möller opened DATAJPA-1464 and commented

public interface JavaUserRepositoryWithImplicitQuery extends Repository<User, Long> { 
    Slice<User> findAll(Pageable pageable); 
}

This repository returns at runtime a PageImpl and a count query is run against the db. As far as I understand Slice and Page, this should not happen.

The linked reproducer (branch is called slice) has tests that check for SliceImpl. Relevant is only the count query and not the implementation of Slice but they seem to be related. Logging is activated where the count query can be observed


Affects: 2.1.2 (Lovelace SR2)

Reference URL: https://bitbucket.org/martinmo/spring-data-jpa-demo/src/4e2605ebfbaad16d973b6dbdc14b6d066b3a7fec/?at=slice

spring-projects-issues avatar Nov 26 '18 15:11 spring-projects-issues

Is there any plans to fix this (or a workaround)? Today I faced this problem with Spring Data JPA 2.7.0

soasada avatar Jun 19 '22 20:06 soasada

Are you saying this is still reproducible with recent releases?

odrotbohm avatar Jun 20 '22 08:06 odrotbohm

yes, here is an example repo that reproduce the issue, it contains a CI pipeline that demonstrates with a test that it fails to return a SliceImpl and returns a PageImpl that contains a total size of the page which triggers the count query that I want to avoid by using Slice. https://github.com/soasada/spring-data-jpa-slice-issue

soasada avatar Jun 20 '22 09:06 soasada

That's not a bug. You are re-declaring the method Page<T> findAll(Pageable pageable) of PagingAndSortingRepository. It's implementation, of course, has to read a PageImpl instance as it has to satisfy the contract of that method. That you re-declare the method with a super type to be returned cannot change anything about that.

The reference docs only show and explain Slice as optimization for dedicated query methods, not for re-declared CRUD methods. As a workaround you should be able to declare a similarly looking query method Slice<T> findAllBy(Pageable pageable) (note the slight difference in naming) that should behave as you suggest.

odrotbohm avatar Jun 20 '22 10:06 odrotbohm

I'm not using JpaRepository or an interface extending PagingAndSortingRepository for doing that, AFAIK CrudRepository does not have the method (Page<T> findAll(Pageable pageable)) so I'm not overriding PagingAndSortingRepository.

soasada avatar Jun 20 '22 10:06 soasada

You actually are, as in fact the JPA implementation of CrudRepository, SimpleJpaRepository implements PagingAndSortingRepository in preparation of our users declaring PASR as repository super type. Page<T> findAll(Pageable) is not a query method, and thus the optimization by using the different query method return type does not work. That's what I am trying to say.

odrotbohm avatar Jun 20 '22 10:06 odrotbohm

ok, I was fooled by the implementation of the CrudRepository interface, thanks for the clarification. I will add a comment to my code to not forget that.

soasada avatar Jun 20 '22 10:06 soasada

That said, I can see why this is not immediately obvious that a call to the method would be executed that way. However, changing that would cause significant rework to the internal routing of calls, and I am not quite sure that I currently oversee the side effects of not routing the method call through the actual implementation but essentially executing a derived query for it. I'll take this to the team for discussion.

Thanks for digging this up, though! 🙃

odrotbohm avatar Jun 20 '22 10:06 odrotbohm

Since this is "worked as designed", I'm closing this ticket.

gregturn avatar Aug 11 '23 12:08 gregturn