I have a method that does a search with filters, so I'm using Specification to build a dynamic query:
public Page<Foo> searchFoo(@NotNull Foo probe, @NotNull Pageable pageable) {
Specification<Foo> spec = Specification.where(null); // is this ok?
if(probe.getName() != null) {
spec.and(FooSpecs.containsName(probe.getName()));
}
if(probe.getState() != null) {
spec.and(FooSpecs.hasState(probe.getState()));
}
//and so on...
return fooRepo.findAll(spec, pageable);
}
There is the possibility that there are no filters specified, so I would list everything without filtering. So having that in mind, how I should initialize spec
? Right now, the code above doesn't work as it always returns me the same result: all the registers of the table, no filtering have been aplied althought and
operations have been made.
FooSpecs:
public class PrescriptionSpecs {
public static Specification<Prescription> containsCode(String code) {
return (root, criteriaQuery, criteriaBuilder) ->
criteriaBuilder.like(root.get(Prescription_.code), "%" + code + "%");
}
// some methods matching objects...
public static Specification<Prescription> hasContractor(Contractor contractor) {
return (root, criteriaQuery, criteriaBuilder) ->
criteriaBuilder.equal(root.get(Prescription_.contractor), contractor);
}
//... also some methods that access nested objects, not sure about this
public static Specification<Prescription> containsUserCode(String userCode) {
return (root, criteriaQuery, criteriaBuilder) ->
criteriaBuilder.like(root.get(Prescription_.user).get(User_.code), "%" + userCode + "%");
}
}
SPring Data Jpa Specifications helps us to create dynamic queries based on the requirement at run time. Spring Data Jpa Specifications allows a combination of the attributes or properties of a domain or entity class and creates a query.
Joining Tables with JPA Specifications select author0_.id as id1_1_, author0_. first_name as first_na2_1_, author0_. last_name as last_nam3_1_ from author author0_ inner join author_books books1_ on author0_.id = books1_. author_id inner join book book2_ on books1_.
Spring Data JPA is not an implementation or JPA provider, it's just an abstraction used to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.
Enable Spring Data JPA by annotating the PersistenceContext class with the @EnableJpaRepositories annotation. Configure the base packages that are scanned when Spring Data JPA creates implementations for our repository interfaces.
Specification.where(null)
works just fine.
It is annotated with @Nullable
and the implementation handles null
values as it should.
The problem is that you are using the and
method as if it would modify the Specification
, but it creates a new one. So you should use
spec = spec.and( ... );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With