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