web-dev-qa-db-fra.com

Hibernation et exception inattendue de fin de sous-arborescence

Je suis un débutant à Hibernate.

J'ai un Item POJO qui contient un Set<String> composé d'étiquettes. Les étiquettes sont contenues dans une autre table de base de données de la table Item, donc je fais une jointure pour remplir le pojo.

J'essaie d'exécuter un exemple de requête simple dans le livre "Java Persistance with Hibernate" où je demande from Item item where 'hello' member of item.labels. Seulement, pour une raison quelconque, je reçois un

 `org.hibernate.hql.ast.QuerySyntaxException: unexpected end of subtree[from /*qualified class path*/.Item item where 'hello' member of item.labels]`

Quelle pourrait être la cause de ce problème?

Voici mes POJO:

public class Item
       private int uuid;
       private Set<String>labels = new HashSet<String>();

       @Id
       public int getUuid(){
          return uuid; 
       }

       @CollectionOfElements
       @JoinTable(name="labels", joinColumns=@JoinColumn(name="uuid"))
       @Column(name="label")
       public Set<String> getLabels(){
            return labels;
       }
 }
22
Scott Fines

Pour les collections de primitives, vous devez utiliser une requête HQL comme ceci:

from Item item join item.labels lbls where 'hello' in (lbls)

PS: 'join' est obligatoire car 'labels' est une variante OneToMany ou ManyToMany, les parenthèses sont obligatoires car 'lbls' est une collection

7
Yuri.Bulkin

De googler autour, il semble que votre collection de paramètres peut être vide. J'ajouterais un chèque vide avant d'appeler la requête.

La leçon est que Google est votre ami. Lorsque vous ne parvenez pas à comprendre un message d'erreur, essayez de le taper dans Google (ou votre moteur préféré.) Il est peu probable que vous soyez la première personne à avoir été confuse.

50
PanCrit

Sur la base des commentaires sur le bogue HHH-5209 , qui est à peu près la même exception levée à partir d'une requête JPQL similaire, je pense que la forme correcte ici est:

select item from Item item where 'hello' in elements(item.labels)

La fonction elements y est la clé. C'est peut-être un peu plus simple que la suggestion de Yuri, car cela évite la jointure explicite.

1
Tom Anderson

Le membre de commande dans le HQL est réservé à l'utilisation d'objets non primitifs. Il y a deux choses que tu peux faire. Vous pouvez soit créer un SQLQuery comme suit:

SQLQuery sQuery = session.createSQLQuery("select * 
                                          from item_table it 
                                          inner join label_table lt 
                                          where it.id = lt.item_id 
                                          and lt.label = 'hello'");
sQuery.list();

Ou vous pouvez créer une classe appelée Label et effectuer les opérations suivantes dans votre HQL:

from Item item, Label label
where label member of item.labels
      and label.label = 'hello'

J'espère que cela t'aides :)

1
jtbradle