JPQL-запрос для элемента в списке, хранящемся с AttributeConverter - PullRequest
0 голосов
/ 15 мая 2018

Как предложил Тобиас Лиефке здесь , я реализовал AttributeConverter для хранения значений списка в одном строковом столбце, разделенном запятыми.

Класс преобразователя:

public class ListNumbersConverter implements AttributeConverter<List<Long>, String>

Поле в классе сущности:

@Column(name = "user_ids", nullable = false)
@Convert(converter = ListNumbersConverter.class)
private List<Long> userIds;

Работает нормально, но я не могу запросить записи для определенных элементов списка. Я попытался использовать оператор IN в запросе JPQL, как показано ниже:

? in userIds 

При этом я получаю только результат, если входной параметр является первым элементом в значении БД. например: значение БД равно «1,2,3». Я могу получить эту запись, если значение входного параметра равно 1 для вышеупомянутого запроса, но не могу получить, если значение равно 2 или 3. Как мне написать свой запрос, чтобы получить все записи, которые содержат определенный элемент?

Моя база данных - MySQL.

1 Ответ

0 голосов
/ 29 мая 2018

Hibernate не знает как конвертер отображает список в столбец.Он не может построить отображение из JPQL ? in userIds в соответствующий фрагмент SQL, так как ему необходимо знать, как реализован ваш конвертер.

Но вы всегда можете построить этот фрагмент SQL самостоятельно, например:

WHERE concat(',', entity.userIds, ',') LIKE concat('%,', ?, ',%')

Первое concat должно гарантировать, что выражение соответствует даже первому и последнему значению списка (которое не будет начинаться или заканчиваться разделителем).

Тамдругие специфичные для БД функции, которые можно использовать, но этот пример работает со всеми типами баз данных, о которых я знаю.

Еще одно замечание: Не пытайтесь присоединиться к запросу userIds - так как он имеет тип basic , даже если это список.См. JavaDoc: @Convert:

Аннотация Convert используется для указания преобразования базового поля или свойства.

Тем не менее Hibernate будет жаловаться, если вы сравните свойАтрибут напрямую с литералом (entity.userIds = '1'), потому что тип атрибута не соответствует типу литерала.Но до тех пор, пока вы используете функцию, подобную выше, для обеих сторон сравнения, она не будет жаловаться.

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