JPQL-запрос: элемент, принадлежащий нескольким категориям - PullRequest
1 голос
/ 01 октября 2019

Имея сущность Предметы , которые имеют поле сбора, называемое категории , мне нужно найти элементы, которые принадлежат как минимум к двум конкретным категориям, но я не могу найти способ построитьправильный запрос JPQL.

@Entity
public class Items {
@ManyToMany (fetch = FetchType.EAGER)
private List<Category> categories;
}

Я могу найти элемент одной категории:

SELECT i FROM Item i WHERE :cat MEMBER OF item.categories

Я могу выбрать элементы любой из нескольких категорий:

SELECT i FROM Item i WHERE :cat1 MEMBER OF item.categories OR :cat MEMBER OF item.categories

Но когда я пытаюсь выбрать элементы, которые имеют по крайней мере две конкретные категории, следующий запрос не получает элементов:

SELECT i FROM Item i WHERE :cat1 MEMBER OF item.categories AND :cat2 MEMBER OF item.categories

Какой правильный способ сделать это?

С наилучшими пожеланиямиПабло.

1 Ответ

1 голос
/ 02 октября 2019

Эта проблема произошла со мной с ObjectDB. Я тоже связался с ними, и это был ответ:

Это, кажется, результат того, как JPQL-запросы перед выполнением преобразуются в SQL-подобный синтаксис. MEMBER OF реализован с использованием JOIN с новой синтетической переменной для итерации по коллекции. В вашем запросе item.categories появляется дважды, но одна и та же синтетическая переменная для итерации по этой коллекции используется для обоих вхождений, и эта переменная не может соответствовать обеим сторонам AND с одинаковым значением.

Возможно, у нас может бытьиспользовать отдельную итерацию для каждого ЧЛЕНА OF, так как результаты, показанные в вашем посте, кажутся неприемлемыми (хотя сам JQPL ведет себя странным образом в некоторых известных случаях из-за преобразования в JOIN). Однако использование отдельных переменных может иногда усложнять и замедлять запрос (например, для запроса OR в вашем сообщении), поэтому любое изменение требует тщательного планирования.

В качестве быстрого решения вы можете заменить AND of MEMBEROF с 2 явными переменными JOIN для итерации по коллекции с 2 независимыми переменными.

Итак, решение состоит в том, чтобы использовать следующий запрос:

SELECT DISTINCT item
FROM Item item JOIN item.categories cat1 JOIN item.categories cat2
WHERE cat1 = :cat1 AND cat2 = :cat2

Я не знаюесли это проблема только для этой конкретной реализации JPA (ObjectDB). Во всяком случае, если у кого-то есть подобная проблема, я надеюсь, что этот пост может помочь.

...