Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use CriteriaBuilder to filter IN multiple ENUM values

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

like image 953
Alex Avatar asked Jan 25 '26 03:01

Alex


1 Answers

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.

like image 95
Alex Avatar answered Jan 27 '26 18:01

Alex



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!