Hibernate Native SQL Query retrieving entities and collections

Ben picture Ben · Aug 25, 2011 · Viewed 51.7k times · Source

This is my situation, I have two basic POJO's which I've given a simple hibernate mapping :

Person
  - PersonId
  - Name
  - Books

Book
  - Code
  - Description

My SQL Query returns rows that look like this :

PERSONID NAME       CODE DESCRIPTION
-------- ---------- ---- -----------
1        BEN        1234 BOOK 1
1        BEN        5678 BOOK 2
2        JOHN       9012 BOOK 3

My hibernate query looks like this :

session.createSQLQuery("select personid, name, code, description from person_books")  
       .addEntity("person", Person.class)
       .addJoin("book", "person.books")
       .list();

This is per section : 18.1.3 of the hibernate documentation : http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/querysql.html#d0e17464

What I expect to get in my list is 2 Person Objects with the contained book objects in the collection of books :

List
 |- Ben
 |   |- Book 1
 |   '- Book 2
 '- John
     '- Book 3

What I am actually seeing is this :

List
 |- Object[]
 |   |- Ben
 |   |   |- Book 1
 |   |   '- Book 2
 |   '- Book 1
 |- Object[]
 |   |- Ben
 |   |   |- Book 1
 |   |   '- Book 2
 |   '- Book 2
 '- Object[]
     |- John
     |   '- Book 3
     '- Book 3

Does anyone know if it's possible to get what I want using this method?

Answer

ehrhardt picture ehrhardt · Jun 20, 2013

Expanding on Mathews answer. To force hibernate to only return a list of persons do:

List<Person> peopleWithBooks = session.createSQLQuery(
   "select {p.*}, {b.*} from person p, book b where <complicated join>").
     .addEntity("p", Person.class)
     .addJoin("b", "p.books")
     .addEntity("p", Person.class)
     .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
     .list();

Associated Book entities will be fetched and initialized without a additional call to the db.

The duplicate

 .addEntity("p", Person.class)

is necessary because

 .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)

operates on the last entity added.