9

I am using Hibernate and I have this query:

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

With this statement, I get all persons from the database. But now, I only want some persons.

My database scheme:

Project <- Project_Person -> Person

So I only want Persons which are a member of a project.

With the SQL statement on the database I get the desired result:

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

So I thought, I can write this with Hibernate:

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

But here I get an error:

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)
 ...

Does anyone has an idea what's wrong here?

Best Regards.

New Error:

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>();

Full Error

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

1 Answer 1

25

HQL queries are written against the object model, not against the database schema.

Therefore your query depends on how you mapped the relationship between persons and projects. For example, in Person has a many-to-one relationship to Project via project property, the query will look like this:

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

EDIT: In the case of many-to-many relationship you need

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

Also not that passing parameters via string concatenation is a bad practice, use setParameter() instead.

Sign up to request clarification or add additional context in comments.

5 Comments

Hmm, but it does not work. I updated my question with the new error, I get. I have a many-to-many relationship, foreign keys project_id and person_id
Now, there is no Hibernate error anymore, but another one: SERVE: Servlet.service() for servlet myproject3 threw exception java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.mydomain.myproject.domain.Person
I updated my question with the full error and the Hibernate SQL statements. Does it also read project values and want to put it into the Person? Is this the cause of the error?
@Tim: Updated, you need select clause in this case, otherwise it returns <Person, Project> pairs.
Someone edit this. .list() replaced by .getResultList().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.