2010-12-15 75 views
9

J'utilise Hibernate et j'ai cette requête:Mise en veille prolongée: org.hibernate.hql.ast.QuerySyntaxException: jeton inattendu

List<Person> list = sess.createQuery("from Person").list(); 

Avec cette déclaration, je reçois toutes les personnes de la base de données. Mais maintenant, je ne veux que quelques personnes.

Mon schéma de base de données:

Projet < - Project_Person -> Personne

Je veux que les personnes qui sont membres d'un projet.

Avec l'instruction SQL sur la base de données que j'obtenir le résultat souhaité:

select * from Person inner join Project_Person 
    on person_id = id 
    where project_id = 1; 

Je pensais, je peux écrire cela avec Hibernate:

List<Person> list = 
    sess.createQuery(
     "from Person inner join Project_Person 
      on person_id = id 
      where project_id = "+projectId).list(); 

Mais ici, je reçois une erreur:

SERVE: Servlet.service() for servlet myproject3 threw exception 
org.hibernate.hql.ast.QuerySyntaxException: unexpected token: on near line 1, column 65 [from com.mydomain.myproject.domain.Person inner join Project_Person on person_id = id where project_id = 1] 
at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:54) 
at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:47) 
at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:82) 
at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:284) 
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:182) 
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136) 
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101) 
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80) 
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:124) 
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:156) 
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:135) 
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1770) 
at sun.reflect.GeneratedMethodAccessor33.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
at java.lang.reflect.Method.invoke(Method.java:597) 
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:344) 
at $Proxy26.createQuery(Unknown Source) 
... 

Est-ce que quelqu'un a une idée de ce qui ne va pas ici?

Cordialement.

Nouvelle erreur:

SERVE: Servlet.service() for servlet myproject3 threw exception 
org.hibernate.QueryException: could not resolve property: project of: com.mydomain.myproject.domain.Person [from com.mydomain.myproject.domain.Person p where p.project.id = :id] 

n: m relation:

@ManyToMany(cascade = CascadeType.ALL) 
@JoinTable(name = "Project_Person", 
    joinColumns = {@JoinColumn(name="project_id", referencedColumnName="id")}, 
    inverseJoinColumns = {@JoinColumn(name="person_id", referencedColumnName="id")} 
) 
private Set<Person> persons = new HashSet<Person>(); 


@ManyToMany(mappedBy="persons") 
private Set<Project> projects = new HashSet<Project>(); 

Erreur pleine

Hibernate: select project0_.id as id1_, project0_.createDate as create2_1_, project0_.description as descript3_1_, project0_.name as name1_ from Project project0_ where project0_.id=1 
Hibernate: select person0_.id as id0_0_, project2_.id as id1_1_, person0_.email as email0_0_, person0_.firstName as firstName0_0_, person0_.lastName as lastName0_0_, project2_.createDate as create2_1_1_, project2_.description as descript3_1_1_, project2_.name as name1_1_ from Person person0_ inner join Project_Person projects1_ on person0_.id=projects1_.person_id inner join Project project2_ on projects1_.project_id=project2_.id where project2_.id=? 
15.12.2010 16:42:26 org.apache.catalina.core.ApplicationDispatcher invoke 
SERVE: Servlet.service() for servlet myproject3 threw exception 
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.mydomain.myproject.domain.Person 

Répondre

24

requêtes HQL sont écrites sur le modèle d'objet, pas contre la base de données schéma.

Par conséquent, votre requête dépend de la façon dont vous cartographié la relation entre les personnes et les projets. Par exemple, dans Person a un beaucoup à une relation à Project via project propriété, la requête ressemblera à ceci:

List<Person> list = sess.createQuery(
    "from Person p where p.project.id = :id") 
    .setParameter("id", projectId) 
    .list(); 

EDIT: Dans le cas de plusieurs-à-plusieurs vous avez besoin

select p from Person p join p.projects proj where proj.id = :id 

De même, pas de passage de paramètres via une concaténation de chaîne est une mauvaise pratique, utilisez plutôt setParameter().

+0

Hmm, mais il ne fonctionne pas. J'ai mis à jour ma question avec la nouvelle erreur, je reçois. J'ai plusieurs à plusieurs, clés étrangères et PROJECT_ID person_id – Tim

+0

Maintenant, il n'y a pas d'erreur de mise en veille prolongée plus, mais l'autre: SERVIR: Servlet.service() pour servlet myproject3 a jeté exception java.lang.ClassCastException: [Ljava .lang.Object; ne peut pas être converti en com.mydomain.myproject.domain.Person – Tim

+0

J'ai mis à jour ma question avec l'erreur complète et les instructions SQL Hibernate. Est-ce qu'il lit également les valeurs du projet et veut le mettre dans la personne? Est-ce la cause de l'erreur? – Tim