Hibernate Native SQL Query для извлечения сущностей и коллекций - PullRequest
19 голосов
/ 25 августа 2011

Это моя ситуация, у меня есть два основных POJO, которые я дал простому отображению гибернации:

Person
  - PersonId
  - Name
  - Books

Book
  - Code
  - Description

Мой SQL-запрос возвращает строки, которые выглядят так:

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

Мой запрос гибернации выглядит так:

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

Это по разделу: 18.1.3 документации гибернации: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/querysql.html#d0e17464

То, что я ожидаю получить в своем списке, это 2 объекта Person с содержащимися в коллекции книгами объектами книги:

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

Что я на самом деле вижу, так это:

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

Кто-нибудь знает, возможно ли получить то, что я хочу, используя этот метод?

Ответы [ 5 ]

35 голосов
/ 20 июня 2013

Расширение ответа Мэтью.Чтобы заставить hibernate возвращать только список лиц, выполните:

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

Связанные сущности Книги будут извлечены и инициализированы без дополнительного вызова в БД.

Дубликат

 .addEntity("p", Person.class)

необходимо, потому что

 .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)

работает с последней добавленной сущностью.

12 голосов
/ 25 августа 2011

У меня работает следующее:

session.createSQLQuery("select p.*, b.* from person p, book b where <complicated join>").
.addEntity("person", Person.class).addJoin("book", "person.books").list();

Возвращает Object[], содержащий список Person, каждый из которых содержит список Book с. Это делается за один выбор SQL. Я думаю, что ваша проблема в том, что вы никого конкретно не называете.

EDIT: метод возвращает Object [], но массив заполняется экземплярами Person и только экземплярами Person.

Если Hibernate не понимает, как сопоставить ваши классы, или если он не может понять, как сопоставить объединение, он вернет список объектов. Убедитесь, что в каждой строке есть только одна комбинация Person / Book.

7 голосов
/ 26 августа 2011

HHH-2831 Собственные запросы SQL с массивами объектов addJoin или return вместо отдельных сущностей

Такое поведение вызвано известной ошибкой.Дох, следовало искать усерднее!

1 голос
/ 26 августа 2011

AFAIK, невозможно получить «объединенную» сущность обратно из SQL-запроса. Вы получите обратно только массив объектов. В этой ситуации я создал новый конструктор для моей объединенной сущности, который принял массив объектов в качестве аргумента. Затем я построил это вручную.

1 голос
/ 25 августа 2011

Должен ли ваш запрос быть в таблице person вместо person_books?

session.createSQLQuery("select * from person")  
   .addEntity("person", Person.class)
   .addJoin("book", "person.books")
   .list();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...