Как использовать CriteriaQuery для запроса коллекции, которая сохраняется как строка, используя аннотацию @Convert? - PullRequest
0 голосов
/ 26 марта 2020

В приложении SpringBoot, использующем Hibernate, у меня есть сущность, похожая на следующую:

@Entity
@Table(...)
public class MyEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", unique = true, nullable = false)
    private Long id;

    @Convert(converter = IntegerListConverter.class) //this maps a set of integers to a string, and vice versa when writing to the DB
    @Column(name = "types", nullable = false)
    private Set<Integer> types;

    //other members, getters and setters omitted for brevity
}

Я выполняю поиск по нескольким параметрам, и поэтому запрос должен быть построен программно для фильтрации на основе на входе переменной. Я хочу написать запрос, эквивалентный следующему SQL:

SELECT * FROM my_entity
WHERE id IN (:ids)
  AND types LIKE '%:type%';

или эквивалентный:

SELECT * FROM my_entity
WHERE id IN (:ids)
  AND CONCAT(',', types) LIKE '%,:type%';

При использовании первого подхода уровень персистентности жалуется на типы не является Сетом. Второй подход работает, если я пишу его с использованием аннотации @Query, но я не могу его использовать, поскольку, как я упоминал ранее, запрос строится условно в зависимости от пользовательского фильтра. Еще одно примечание: я выполняю запрос к большому набору данных (например, ~ 100 000 подходящих записей) для MySQL, а выполнение отдельных запросов будет включать передачу большого объема данных, что делает его медленным (т.е. ~ 20 секунд).

Примечание: пожалуйста, не беспокойтесь о том, как плохо хранить отношения «один ко многим» в одной таблице. Были рассмотрены компромиссы, и система по какой-то причине разработана таким образом.

Помощь оценена. Заранее спасибо.

1 Ответ

0 голосов
/ 27 марта 2020

Аннотируйте его с помощью @ Basi c, тогда это должно сработать. IMO, вам следует рассмотреть возможность использования типа JSON в MySQL вместо того, чтобы избежать пользовательского «разбора», который вам нужно сделать, чтобы иметь возможность найти отдельные значения. Я думаю, что вы даже можете индексировать это правильно, когда вы переключаетесь на JSON.

...