i am using a heavily modified version of the code in Carl Mapada's Advanced Search and Filtering article and it was actually working out very well for me until i had to add pageable. and like many others using Speccification with Pageable i had a problem with the count query. so i wrote a CustomRepository and overrode the readPage so it doesn't count. all good, paging is working but except i believe i need a separate count query if i want to show something like "1 to 100 of 1482 results." (the current total is just the total from the paging.)
so i went down the path of trying to figure out a way to get a total count with my on the fly queries built with the SpecificationBuilder implementation i have. i have not been successful for the last day or so but going to the extremes to try to solve my problem i noticed something interesting...
if in my service i call a repository method with the same Specification instance twice then i get an error (even without pageable)...
MyEntitySpecBuilder builder = new MyEntitySpecBuilder(filter, specs);
Specification<MyEntity> spec = builder.build();
List<MyEntity> entities1 = myEntityRepository.findAll(spec);
List<MyEntity> entities2 = myEntityRepository.findAll(spec);
JpaSystemException: unable to location property named xyz on blah.blah.EntityClassAttribute occurs on the second call to findAll(...)
yet, if i do this, there is no error...
MyEntitySpecBuilder builder = new MyEntitySpecBuilder(filter, specs);
Specification<MyEntity> spec = builder.build();
List<MyEntity> entities1 = myEntityRepository.findAll(spec)
List<MyEntity> entities2 = myEntityRepository.findAll(builder.build());
the only reason i stumbled upon that is that i was trying to get a custom count query going but using the same Specification instance as i use for getting the page info but it wasn't working so i decided to just start with having the service do two different queries with the same Specification instance (though inefficient, it was a start) and i stumbled upon this.
so here are my questions...
- if i have a situation where multiple Specification parts are used to create a query (as in the Advanced Search and Filtering example) and i want a count, is there a suggested way to do it, hopefully in a CustomRepository (and not in a Service)? i was thinking of having a custom repository method where i pass the specification builder and get two separate instances of the specification in the respotory method, one for getting the count and one for getting the results.
- but my main question now is... is the Specification instance being modified in some way after it is used the first time or why are two separate instances working one after another but not the same instance?
here is the solution i went with for my second question. this is something put together as opposed to finding it in a search so i'm not sure if there is a better way but it works. i forgot to note that i am using spring data jpa 2.2.7 and so maybe the upgraded spring version works differently (we are slow to upgrade libs a lot.)