JPA 2查询返回不完整的结果

时间:2010-10-21 18:45:52

标签: java jpa-2.0 jpql

以下查询仅匹配select子查询中找到的第一个值,即使所有值都匹配SELECT p FROM Profile p WHERE p.id IN (SELECT u.group FROM User u WHERE u.id = ?1)

子查询返回逗号分隔的列表,如:1,2,3。查询应返回所有三个子查询选择结果的匹配项。谁知道什么可能是错的?感谢。

2 个答案:

答案 0 :(得分:2)

IN子句在JPQL和SQL中都不会以这种方式工作。

(..)内的值不是“以逗号分隔的字符串”,而是值列表。此列表可以字面指定为逗号分隔的字符串,也可以由子查询生成,如您的情况。也就是说,查询中的条件为p.id IN ("1,2,3")(而非p.id IN (1,2,3)),因此不会产生所需的结果。

因此,您无法使用查询语言(JPQL或SQL)的强大功能来针对非规范化架构编写查询(您的列包含值列表,因此它违反了1NF)。如果ProfileUser之间存在多对多关系,请将其表示为与中间联接表的多对多关系。

答案 1 :(得分:1)

虽然IN运算符支持与子查询的结果进行比较,但您正在做的事情无法正常工作(我很惊讶您甚至得到了一个结果)。在进一步讨论之前,让我引用JPA 2.0规范:

  

4.6.9在表达式中

     

使用的语法   比较运算符[NOT] IN in a   条件表达式如下:

 in_expression ::=
    {state_field_path_expression | type_discriminator} [NOT] IN
        { ( 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为false,   并且相当于表达式   (o.country = ’UK’) OR (o.country = ’US’) OR (o.country = ’ France’)

     o.country NOT IN (’UK’, ’US’, ’France’)

UK为false,为true   对于Peru,并且相当于   表达NOT ((o.country = ’UK’) OR (o.country = ’US’) OR (o.country = ’France’))

     

必须至少有一个元素   以逗号分隔的列表定义   IN的值集   表达

     

如果是a的值   IN或NOT IN表达式中的 state_field_path_expression in_item NULL或未知,   表达式的值是未知的。

     

请注意使用集合值   输入参数意味着a   静态查询无法预编译。

所以,首先,p.id与subselect的返回类型不匹配(实际上是一个“次要”问题)。

其次,这是一个主要问题和误解,你的查询不会产生类似的结果(使用“伪代码”):

p.id IN (1, 2, 3) 

这是你想要的 - 但是在

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

这显然不是你想要的,也不行。

我唯一的建议是:对数据库进行normarlize。