Используйте CriteriaBuilder для фильтрации нескольких значений ENUM - PullRequest
1 голос
/ 09 октября 2019

Я хочу построить запрос с помощью CriteriaBuilder и добавить предикат в инструкцию where, чтобы отфильтровать одно из полей моего объекта из потенциального списка значений ENUM.

Несмотря на этот похожий пост: Фильтрация данных с помощью CriteriaBuilder для сравнения значений перечисления с неработающими литералами

Мне не удалось заставить мой код работать. Вот «упрощенный» объект:

//BUNCH OF ANNOTATIONS
public class Action {
    @Column(name = "CONTEXT")
    @Enumerated(EnumType.STRING)
    private ActionContext context = ActionContext.SALE;

    // ...
}

Мое перечисление:

public enum ActionContext {
    SALE,
    ORDER,
    OTHER
}

И в моих фильтрах я могу, например, получить что-то вроде «ПРОДАЖА, ЗАКАЗАТЬ».

Итак, я создал пользовательскую спецификацию, и когда я ее создаю, я делаю это:

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;

Часть после просто выполняет запрос, он работает для других фильтров ... нофакт, что у моей сущности есть перечисление: когда я запускаю тест с этими фильтрами (отправляя фильтр "SALE, ORDER" для ex), я получаю следующую ошибку:

Значение параметра [SALE] не былосоответствует ожидаемому типу [com.mycompany.domain.enums.ActionContext

. Я также попытался заменить CriteriaBuilder.in на .or () и поместить в коллекцию проанализированных токенов, но у меня была та же ошибка.

И да, я уверен, что это не ошибка синтаксического анализа, потому что, когда я помещаю точку останова в этот раздел swich / case, я вижу правильно построенный массив contextTokens с хорошим значением в нем. А в спецификации «в» я вижу, как устанавливаются правильные значения.

Кто-нибудь знает, что мне не хватает? спасибо большое

1 Ответ

0 голосов
/ 10 октября 2019

ОК. Я сравнивал Enum со String и не видел этого ... Так что в этом случае вам просто нужно преобразовать ActionContext ENUM с ActionContext.valueOf(token) или наоборот, преобразовав root.get(CONTEXT_FILTER_NAME).as(String.class).

Надеюсь, что это помогает людям, которые похожи на меня, иногда в каком-то туннельном видении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...