Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

JPA CriteriaBuilder und IN

37 views
Skip to first unread message

Chris Seidel

unread,
Aug 18, 2012, 11:16:58 AM8/18/12
to
Hi,

wenn ich mit dem CriteriaBuilder eine IN-Abfrage bauen möchte:

builder.in("foo").value(mySet);

bekomme ich folgende Exception beim Erzeugen der Query

java.lang.IllegalArgumentException: Parameter value [Test] was not
matching type [java.util.Set]
at
org.hibernate.ejb.AbstractQueryImpl.registerParameterBinding(AbstractQueryImpl.java:340)
at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:364)
at
org.hibernate.ejb.criteria.CriteriaQueryCompiler$1$1.bind(CriteriaQueryCompiler.java:194)
at
org.hibernate.ejb.criteria.CriteriaQueryCompiler.compile(CriteriaQueryCompiler.java:247)
at
org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:603)

Bewirken sollte das eigentlich: from Bar where foo in ('Test')

foo ist vom Typ java.util.Set.

Was hab ich falsch gemacht?

Danke

Achim Peters

unread,
Aug 18, 2012, 12:10:20 PM8/18/12
to
Am 18.08.2012 17:16, schrieb Chris Seidel:
> wenn ich mit dem CriteriaBuilder

Kenne ich leider nicht.

> eine IN-Abfrage bauen mï¿œchte:
>
> builder.in("foo").value(mySet);
>
> bekomme ich folgende Exception beim Erzeugen der Query
>
> java.lang.IllegalArgumentException: Parameter value [Test] was not
> matching type [java.util.Set]

> foo ist vom Typ java.util.Set.

Interessanter wï¿œre wahrscheinlich, welchen Typ mySet hat. Wenn Du jetzt
ebenfalls "vom Typ java.util.Set" sagst, dann zeig mal den Code dazu,
denn die Run-Time-Umgebung scheint da anderer Meinung zu sein.

Bye
Achim

Chris Seidel

unread,
Aug 18, 2012, 12:33:17 PM8/18/12
to
On Sat, 18 Aug 2012 18:10:20 +0200, Achim Peters <Achim...@gmx.de>
wrote:

> Interessanter wäre wahrscheinlich, welchen Typ mySet hat. Wenn Du jetzt
> ebenfalls "vom Typ java.util.Set" sagst, dann zeig mal den Code dazu,
> denn die Run-Time-Umgebung scheint da anderer Meinung zu sein.


Set mySet = new HashSet();
mySet.add("foo");

Achim Peters

unread,
Aug 18, 2012, 12:50:01 PM8/18/12
to
Am 18.08.2012 18:33, schrieb Chris Seidel:
> On Sat, 18 Aug 2012 18:10:20 +0200, Achim Peters <Achim...@gmx.de>
> wrote:
>
>> Interessanter wï¿œre wahrscheinlich, welchen Typ mySet hat. Wenn Du jetzt
>> ebenfalls "vom Typ java.util.Set" sagst, dann zeig mal den Code dazu,
>> denn die Run-Time-Umgebung scheint da anderer Meinung zu sein.
>
>
> Set mySet = new HashSet();
^ setz doch mal "java.util." davor.

> mySet.add("foo");

| builder.in("foo").value(mySet);

| java.lang.IllegalArgumentException: Parameter value [Test] was not
| matching type [java.util.Set]

Und wo verwendest Du "Test"?

Bye
Achim

Chris Seidel

unread,
Aug 18, 2012, 12:59:27 PM8/18/12
to
On Sat, 18 Aug 2012 18:50:01 +0200, Achim Peters <Achim...@gmx.de>
wrote:

>> mySet.add("foo");
>
> | builder.in("foo").value(mySet);
>
> | java.lang.IllegalArgumentException: Parameter value [Test] was not
> | matching type [java.util.Set]
>
> Und wo verwendest Du "Test"?

Sorry, war aus dem Gedächtnis, Code nicht zur Hand.

War natürlich mySet.add("Test");

Achim Peters

unread,
Aug 18, 2012, 1:04:33 PM8/18/12
to
Am 18.08.2012 18:59, schrieb Chris Seidel:

> Code nicht zur Hand.

Dann ist ein gerne gemachter Fehler, den Fehler im Programm im
Gedï¿œchtnis nicht gemacht zu haben. Poste doch den entsprechenden Code
mal per C&P, wenn er Dir wieder vorliegt. Mï¿œglicherweise ist's nur ein
Tippfehler.

Bye
Achim

Chris Seidel

unread,
Aug 23, 2012, 6:07:41 AM8/23/12
to
On Sat, 18 Aug 2012 19:04:33 +0200, Achim Peters <Achim...@gmx.de>
wrote:

> Am 18.08.2012 18:59, schrieb Chris Seidel:
>
>> Code nicht zur Hand.
>
> Dann ist ein gerne gemachter Fehler, den Fehler im Programm im
> Gedächtnis nicht gemacht zu haben. Poste doch den entsprechenden Code
> mal per C&P, wenn er Dir wieder vorliegt. Möglicherweise ist's nur ein
> Tippfehler.
>
> Bye
> Achim

Scheint ein Hibernate-Bug zu sein, ich habe 3.6.8 final:

https://hibernate.onjira.com/browse/HHH-5440

Da soll der aber schon behoben sein..

Ich hab das Beispiel aus HHH-5440 mal genommen und mit 4.1.6 final laufen
lassen:

Da baut Hinerate so ne Query, die ist irgendwie kaputt?

from user user0_ cross join user_roles roles1_ where
user0_.id=roles1_.user and (. in (?))

In JPA-QL ist das "from User u where u.roles in (?1)". Wird IN bei einem
Set vlt. gar nicht unterstützt?

Chris Seidel

unread,
Aug 23, 2012, 7:23:16 AM8/23/12
to
On Thu, 23 Aug 2012 12:07:41 +0200, Chris Seidel <cr_s...@arcor.de>
wrote:

> In JPA-QL ist das "from User u where u.roles in (?1)". Wird IN bei einem
> Set vlt. gar nicht unterstützt?

Laut https://forum.hibernate.org/viewtopic.php?f=1&t=1007606 ist das keine
gültige JPA-Query. Hä? Wieso das denn?

member of fkt dageben genauso nicht, Bug im Hibernate, unresolved.

Danke Anke

Chris Seidel

unread,
Aug 23, 2012, 8:16:55 AM8/23/12
to
On Thu, 23 Aug 2012 13:23:16 +0200, Chris Seidel <cr_s...@arcor.de>
wrote:


Das geht...

from User u, IN(u.roles) r where r in (?1)

Warum

from User u where u.roles in (?1)

Nicht?

Patrick Roemer

unread,
Aug 23, 2012, 8:27:41 AM8/23/12
to
Responding to Chris Seidel:

in_expression ::=
{state_field_path_expression | type_discriminator} [NOT] IN
{ ( in_item {, in_item}* ) | (subquery) |
collection_valued_input_parameter }

state_field_path_expression ::=
general_identification_variable .
{single_valued_object_field .}* state_field

in_item ::= literal | single_valued_input_parameter

> Das geht...
>
> from User u, IN(u.roles) r where r in (?1)

Von der Spec her duerfte das eigentlich nicht gehen.

- "r" ist kein field path.
- Dein "?1" ist Deiner Beschreibung nach nicht single-valued, muesste
also "?1" statt "(?1)" sein.

> Warum
>
> from User u where u.roles in (?1)
>
> Nicht?

Auf der linken Seite muss ein state field (single valued) stehen. (Und
selbes Problem wie oben mit dem "(?1)".)

Viele Gruesse,
Patrick

Chris Seidel

unread,
Aug 23, 2012, 8:49:16 AM8/23/12
to
On Thu, 23 Aug 2012 14:27:41 +0200, Patrick Roemer
<sang...@netcologne.de> wrote:

>> from User u, IN(u.roles) r where r in (?1)
>
> Von der Spec her duerfte das eigentlich nicht gehen.

Ist auch überaus seltsam, hab ich bisher nie gesehen.

> - "r" ist kein field path.
> - Dein "?1" ist Deiner Beschreibung nach nicht single-valued, muesste
> also "?1" statt "(?1)" sein.

Ja, stimmt. Interessiert Hibernate aber nicht, da ist es wohl gnädig...

>> from User u where u.roles in (?1)
>>
>> Nicht?
>
> Auf der linken Seite muss ein state field (single valued) stehen. (Und
> selbes Problem wie oben mit dem "(?1)".)

OK; seh ich ein.


Ergo ist member of der einzige Weg, die @CollectionOfElements via Set
abzufragen?

Alternativ das Set auflösen und dann: u.roles = ?1 OR u.roles =?2 etc?


> in_expression ::=
> {state_field_path_expression | type_discriminator}

Hm... type_discriminator...

Man könnte also einen Type abfragen?

Ich meine jetzt den Type-Discr. bei Inheritance.

Patrick Roemer

unread,
Aug 23, 2012, 9:09:50 AM8/23/12
to
Responding to Chris Seidel:
> On Thu, 23 Aug 2012 14:27:41 +0200, Patrick Roemer
> <sang...@netcologne.de> wrote:
>
>>> from User u, IN(u.roles) r where r in (?1)
>>
>> Von der Spec her duerfte das eigentlich nicht gehen.
>
> Ist auch ï¿œberaus seltsam, hab ich bisher nie gesehen.

Die collection member declaration mit "IN"? Das ist im Prinzip
aequivalent zu "from User u join u.roles r".

>> - "r" ist kein field path.
>> - Dein "?1" ist Deiner Beschreibung nach nicht single-valued, muesste
>> also "?1" statt "(?1)" sein.
>
> Ja, stimmt. Interessiert Hibernate aber nicht, da ist es wohl gnï¿œdig...

Was sich insbesondere bei dem "r" gluecklich fuegt... Mir ist nicht ganz
klar, warum die Spec da einen field path verlangt.

> Ergo ist member of der einzige Weg, die @CollectionOfElements via Set
> abzufragen?

Duerfte auch nicht gehen.

collection_member_expression ::=
entity_or_value_expression [NOT] MEMBER [OF]
collection_valued_path_expression

Linke Seite darf nicht collection valued sein. "?1 member u.roles" fuer
einen Set-Parameter geht also nicht.

> Alternativ das Set auflï¿œsen und dann: u.roles = ?1 OR u.roles =?2 etc?

Noe, da stimmen ja die Typen der beiden Seiten nicht ueberein.

"?1 member u.roles or ?2 member u.roles or ..."

Die sinnigste Variante scheint schon die collection member declaration
zu sein, aber die duerfte nicht portabel sein.

>> in_expression ::=
>> {state_field_path_expression | type_discriminator}
>
> Hm... type_discriminator...
>
> Man kï¿œnnte also einen Type abfragen?
>
> Ich meine jetzt den Type-Discr. bei Inheritance.

Yep. "from User u where type(u) in (Manager, Administrator)"

Viele Gruesse,
Patrick

Chris Seidel

unread,
Aug 23, 2012, 11:02:47 AM8/23/12
to
On Thu, 23 Aug 2012 15:09:50 +0200, Patrick Roemer
<sang...@netcologne.de> wrote:

> collection_member_expression ::=
> entity_or_value_expression [NOT] MEMBER [OF]
> collection_valued_path_expression
>
> Linke Seite darf nicht collection valued sein. "?1 member u.roles" fuer
> einen Set-Parameter geht also nicht.

Stimmt.

>> Alternativ das Set auflösen und dann: u.roles = ?1 OR u.roles =?2 etc?
>
> Noe, da stimmen ja die Typen der beiden Seiten nicht ueberein.

Stimmt auch :)

> "?1 member u.roles or ?2 member u.roles or ..."

Ja ok.

> Die sinnigste Variante scheint schon die collection member declaration
> zu sein, aber die duerfte nicht portabel sein.

Du meinst das geht ev. nur bei Hibernate?

> Yep. "from User u where type(u) in (Manager, Administrator)"

Ah, cool.

Thx!

Chris Seidel

unread,
Aug 23, 2012, 11:06:55 AM8/23/12
to
On Thu, 23 Aug 2012 17:02:47 +0200, Chris Seidel <cr_s...@arcor.de>
wrote:

>> Yep. "from User u where type(u) in (Manager, Administrator)"

Hm... wie macht man das via Criteria-API?

Patrick Roemer

unread,
Aug 23, 2012, 12:16:59 PM8/23/12
to
Responding to Chris Seidel:

>> Die sinnigste Variante scheint schon die collection member declaration
>> zu sein, aber die duerfte nicht portabel sein.
>
> Du meinst das geht ev. nur bei Hibernate?

Die collection member declaration selber sollte natuerlich portabel
sein, aber eine identification variable (statt eines field paths) auf
der linken Seite der in expression scheint mir die Spec nicht
herzugeben, von daher nicht portabel.

Viele Gruesse,
Patrick

Chris Seidel

unread,
Aug 24, 2012, 3:55:52 AM8/24/12
to
On Thu, 23 Aug 2012 17:06:55 +0200, Chris Seidel <cr_s...@arcor.de>
wrote:


>>> Yep. "from User u where type(u) in (Manager, Administrator)"
>
> Hm... wie macht man das via Criteria-API?

So jedenfalls scheinbar nicht?

Predicate pred = builder.equal(query.from(User.class).type(),
builder.literal(User.class));

Caused by: java.lang.IllegalArgumentException: Unexpected call on
EntityTypeExpression#render
at
org.hibernate.ejb.criteria.expression.PathTypeExpression.render(PathTypeExpression.java:48)
at
org.hibernate.ejb.criteria.predicate.ComparisonPredicate.render(ComparisonPredicate.java:178)
at
org.hibernate.ejb.criteria.predicate.CompoundPredicate.render(CompoundPredicate.java:128)
at
org.hibernate.ejb.criteria.QueryStructure.render(QueryStructure.java:258)
at
org.hibernate.ejb.criteria.CriteriaQueryImpl.render(CriteriaQueryImpl.java:340)
at
org.hibernate.ejb.criteria.CriteriaQueryCompiler.compile(CriteriaQueryCompiler.java:216)
at
org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:605)


Obwohl hier doch so beschrieben (ganz unten)?

http://www.objectdb.com/java/jpa/query/jpql/path

Chris Seidel

unread,
Aug 24, 2012, 3:56:44 AM8/24/12
to
On Thu, 23 Aug 2012 18:16:59 +0200, Patrick Roemer
<sang...@netcologne.de> wrote:

> Die collection member declaration selber sollte natuerlich portabel
> sein, aber eine identification variable (statt eines field paths) auf
> der linken Seite der in expression scheint mir die Spec nicht
> herzugeben, von daher nicht portabel.

Ja, mein ich ja, dass ggf. nur Hibernate das so implementiert, es in der
Spec aber nicht definiert ist.

Thx.

Chris Seidel

unread,
Aug 29, 2012, 4:07:31 AM8/29/12
to
On Fri, 24 Aug 2012 09:55:52 +0200, Chris Seidel <cr_s...@arcor.de>
wrote:

> Predicate pred = builder.equal(query.from(User.class).type(),
> builder.literal(User.class));

OK; Bug in Hib 3.6, fkt. in 4.1
0 new messages