J'ai une méthode qui fait une recherche avec des filtres, donc j'utilise spécification pour construire une requête dynamique:
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);
}
Il y a la possibilité qu'aucun filtre ne soit spécifié, donc je listerais tout sans filtrer. Donc, ayant cela à l'esprit, comment dois-je initialiser spec
? Pour le moment, le code ci-dessus ne fonctionne pas car il me renvoie toujours le même résultat: tous les registres de la table, aucun filtrage n'a été appliqué bien que des opérations and
aient été effectuées.
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 + "%");
}
}
Specification.where(null)
fonctionne très bien. Il est annoté de @Nullable
et l'implémentation gère les valeurs null
comme il se doit.
Le problème est que vous utilisez la méthode and
comme si elle modifierait la Specification
, mais elle en crée une nouvelle. Vous devez donc utiliser
spec = spec.and( ... );