Hibernate Native SQL Query для извлечения сущностей и коллекций
Это моя ситуация, у меня есть два основных 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
То, что я ожидаю получить в своем списке, это 2 объекта Person с объектами book, содержащимися в коллекции книг:
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 ответов
Такое поведение вызвано известной ошибкой. Доу, следовало искать усерднее!
Расширяя ответ Мэтью. Чтобы заставить 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)
работает с последней добавленной сущностью.
Следующие работы для меня:
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
s. Это делается за один выбор SQL. Я думаю, что ваша проблема в том, что вы никого конкретно не называете.
EDIT: метод возвращает Object[], но массив заполняется экземплярами Person и только экземплярами Person.
Если Hibernate не понимает, как сопоставить ваши классы, или если он не может понять, как сопоставить объединение, он вернет список объектов. Убедитесь, что у вас есть только один Person
/Book
комбинация на каждой линии.
Ваш запрос должен быть в таблице person вместо person_books?
session.createSQLQuery("select * from person")
.addEntity("person", Person.class)
.addJoin("book", "person.books")
.list();
AFAIK, невозможно получить "объединенную" сущность обратно из SQL-запроса. Вы получите обратно только массив объектов. В этой ситуации я создал новый конструктор для моей объединенной сущности, который принял массив объектов в качестве аргумента. Затем я построил это вручную.