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?
Hibernate provide option to execute native SQL queries through the use of SQLQuery object. Hibernate SQL Query is very handy when we have to execute database vendor specific queries that are not supported by Hibernate API.
In some cases it can happen Hibernate/JPA does not generate the most efficient statements, so then native SQL can be faster - but with native SQL your application loses the portability from one database to another, so normally is better to tune the Hibernate/JPA Query mapping and the HQL statement to generate more ...
In JPA, you can create a query using entityManager. createQuery() . You can look into API for more detail. Native query refers to actual sql queries (referring to actual database objects).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With