Запрос JPA 2, возвращающий неполные результаты - PullRequest
1 голос
/ 21 октября 2010

Следующий запрос соответствует только первому значению, найденному в подзапросе select, даже если есть совпадения для всех значений SELECT p FROM Profile p WHERE p.id IN (SELECT u.group FROM User u WHERE u.id = ?1)

Подзапрос возвращает список через запятую, например: 1,2,3.Запрос должен возвращать совпадения для всех трех результатов выбора подзапроса.Кто-нибудь знает, что может быть не так?Спасибо.

Ответы [ 2 ]

2 голосов
/ 22 октября 2010
Предложение

IN не работает таким образом ни в JPQL, ни в SQL.

Значение внутри (..) - это не «строка, разделенная запятыми», это список значений.Этот список может быть указан буквально как строка, разделенная запятыми, или он может быть создан подзапросом, как в вашем случае.То есть условие в вашем запросе работает как p.id IN ("1,2,3") (а не p.id IN (1,2,3)), поэтому оно не дает желаемого результата.

Таким образом, вы не можете использовать возможности языков запросов (JPQL илиSQL) для написания запросов к денормализованной схеме (ваш столбец содержит список значений, поэтому он нарушает 1NF ).Если у вас есть отношение «многие ко многим» между Profile s и User s, выразите его как отношение «многие ко многим» с промежуточной таблицей соединений.

1 голос
/ 22 октября 2010

Хотя оператор IN поддерживает сравнение с результатами подзапроса , то, что вы делаете, не может работать (и я удивлен, что вы даже получили один результат). Прежде чем идти дальше, позвольте мне процитировать спецификацию JPA 2.0:

4.6.9 В выражениях

Синтаксис для использования оператор сравнения [NOT] IN в Условное выражение выглядит следующим образом:

 in_expression ::=
    {state_field_path_expression | type_discriminator} <b>[NOT] IN</b>
        { ( in_item {, in_item}* ) | (subquery) | collection_valued_input_parameter }
in_item ::= literal | single_valued_input_parameter 

state_field_path_expression должен иметь строку, число, дату, время, метка времени или значение перечисления.

Литерал и / или входной параметр значения должны быть как одинаковыми тип абстрактной схемы state_field_path_expression в типе. (См. Раздел 4.12).

Результаты подзапроса должны быть как и того же типа абстрактной схемы state_field_path_expression в типе . Подзапросы обсуждаются в Раздел 4.6.16.

Примеры:

o.country IN (’UK’, ’US’, ’France’) верно для UK и ложно для Peru, и эквивалентно выражению (o.country = ’UK’) OR (o.country = ’US’) OR (o.country = ’ France’).

o.country NOT IN (’UK’, ’US’, ’France’) ложно для UK и верно для Peru, и эквивалентно выражение NOT ((o.country = ’UK’) OR (o.country = ’US’) OR (o.country = ’France’)).

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

Если значение state_field_path_expression или in_item в выражении IN или NOT IN равно NULL или неизвестно, Значение выражения неизвестно.

Обратите внимание, что использование коллекционных ценностей входной параметр будет означать, что статический запрос не может быть предварительно скомпилирован.

Итак, во-первых, p.id не соответствует типу возврата подвыбора (что на самом деле является «второстепенной» проблемой).

Во-вторых, и это серьезная проблема и неправильное понимание, ваш запрос не приведет к чему-то вроде этого (с использованием «псевдокода»):

p.id IN (1, 2, 3) 

это то, что вы хотели бы - но в

p.id IN (’1,2,3’) 

что, очевидно, не то, что вы хотите, и не будет работать.

Мой единственный совет: нормализовать вашу базу данных.

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