While the IN
operator supports comparison against the results of a subquery, what you're doing can't work (and I'm surprised that you even get one result). Before going further, let me quote the JPA 2.0 specification:
4.6.9 In Expressions
The syntax for the use of the
comparison operator [NOT] IN in a
conditional expression is as follows:
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
The state_field_path_expression
must have a string, numeric, date,
time, timestamp, or enum value.
The literal and/or input parameter
values must be like the same
abstract schema type of the
state_field_path_expression in type. (See Section 4.12).
The results of the subquery must be
like the same abstract schema type of the
state_field_path_expression in type. Subqueries are discussed in
Section 4.6.16.
Examples:
o.country IN (’UK’, ’US’, ’France’)
is true for UK
and false for Peru
,
and is equivalent to the expression
(o.country = ’UK’) OR (o.country =
’US’) OR (o.country = ’ France’)
.
o.country NOT IN (’UK’, ’US’,
’France’)
is false for UK
and true
for Peru
, and is equivalent to the
expression NOT ((o.country = ’UK’) OR
(o.country = ’US’) OR (o.country =
’France’))
.
There must be at least one element in
the comma separated list that defines
the set of values for the IN
expression.
If the value of a
state_field_path_expression or in_item in an IN or NOT IN expression is NULL
or unknown, the
value of the expression is unknown.
Note that use of a collection-valued
input parameter will mean that a
static query cannot be precompiled.
So, first, p.id
doesn't match the return type of the subselect (which is actually a "minor" issue).
Second, and this is a major issue and misunderstanding, your query won't result in something like this (using "pseudo code"):
p.id IN (1, 2, 3)
which is what you'd like - but in
p.id IN (’1,2,3’)
which obviously is not what you want, and won't work.
My only advice: normarlize your database.