I want to construct a query with CriteriaBuilder, and to add a Predicate into the where instruction, to filter one of my object field from a potential list of ENUM values.
Despite this similar post : Filtering data with CriteriaBuilder to compare enum values with literals not working
I didn't managed to make my code works. Here is the "simplified" object:
//BUNCH OF ANNOTATIONS
public class Action {
@Column(name = "CONTEXT")
@Enumerated(EnumType.STRING)
private ActionContext context = ActionContext.SALE;
// ...
}
My enum is:
public enum ActionContext {
SALE,
ORDER,
OTHER
}
And in my filters, I can for example receive something like "SALE,ORDER".
So I created a custom Specification, and when I construct it, I'm doing this :
private List<Predicate> filters = new ArrayList<>();
//...
// filterValue is a String, it can be "SALE,ORDER" for ex.
case CONTEXT_FILTER_NAME:
if (filterValue != null && !filterValue.isEmpty()) {
String[] contextTokens = filterValue.split(",");
CriteriaBuilder.In<String> inClause = cb.in(root.get(CONTEXT_FILTER_NAME));
Arrays.asList(contextTokens).forEach(inClause::value);
filters.add(inClause);
}
break;
The part after is just doing the query, it works for other filters ... but the fact my entity have an enum : when I run a test with these filters (sending "SALE,ORDER" filter for ex), I get the following error :
Parameter value [SALE] did not match expected type [com.mycompany.domain.enums.ActionContext
I also tried by replacing CriteriaBuilder.in by .or() and putting in the collection of parsed tokens, but I had the same error.
And yes, I'm sure it's not a parsing error, because when I put a breakpoint in this swich/case section, I see the correctly constructed contextTokens array with good value in it. And in the Specification 'in' I can see the correct values being set.
Does anybody know what I'm missing ? thx a lot
OK I was comparing Enum with String, and I didn't see this ...
So you just have in this cases to convert ActionContext ENUM with ActionContext.valueOf(token) or on the other way around, converting the root.get(CONTEXT_FILTER_NAME).as(String.class).
Hope it helps people, that are like me, sometimes in a kind of tunnel vision.
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