hello! I'm trying to build a custom filter for a data grid at runtime. I'm using spring boot and vaadin 8 for data presentation. Vaadin knowledge is irrelevant to this question.
How i'm doing: I built a hashmap for the filters.
private HashMap<String, Specification<ARInteraction>> interactionSpecifications =
new HashMap<>();
Each filter text field adds or removes a specification to the map:
TextField filterOwner = new TextField("Filter");
filterOwner.addValueChangeListener(nv -> {
if (StringUtils.isNotEmpty(nv.getValue())) {
interactionSpecifications.put("owner", ARInteractionSpecifications
.withOwnerEmail(nv.getValue()));
} else {
interactionSpecifications.remove("owner");
}
refreshContent();
});
When the field data changes, a custom specification is added or substituted (or removed) from the specifications map.
Then I call to refresh the data view content, which causes the query to fetch data to be run.
To build the specification to query the data, I simply add all specifications by applying an 'and' operation between them.
private Specification<ARInteraction> buildSpecification() {
// No specs
if (interactionSpecifications.isEmpty())
return null;
// Assembles all specs together
Specification<ARInteraction> ret = null;
for (Specification<ARInteraction> spec : interactionSpecifications.values()) {
if (ret == null) {
ret = Specification.where(spec);
} else {
ret.and(spec);
}
}
return ret;
}
What I expected to happen is that, with both filters applied, only entites that comply with both specifications are fetched.
What actually happens is that if I set the status specification alone (not shown here) it works, if I set the owner email filter it also works, but if I set both, all interactions from that owner are shown ignoring the status filter.
how are you?
Specification behaviour is immutable, so you should be assigning the ret specification with the and operation. Beginner mistake.
for (Specification<ARInteraction> spec : interactionSpecifications.values()) {
if (ret == null) {
ret = Specification.where(spec);
} else {
ret = ret.and(spec); //Assign the ret so that specs are actually added.
}
}