2011-08-25 2 views
16

Это моя ситуация, у меня есть два основные POJO, который я дал простое отображение гибернации:Hibernate Native SQL Query извлечения сущности и коллекции

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 

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

ответ

1

Должен ли ваш запрос находиться на столе человека вместо person_books?

session.createSQLQuery("select * from person") 
    .addEntity("person", Person.class) 
    .addJoin("book", "person.books") 
    .list(); 
+0

Я упростил этот пример ради краткости. В моем фактическом использовании «person_books» представляет собой сложный запрос, hibernate не имеет способа получить информацию для «книги», если я не предоставил ее в запросе. Я извлекаю большое количество строк для Person и предпочитаю не выполнять дополнительный запрос для поиска книг для каждого человека. Если я не смогу найти решение, я, вероятно, буду использовать этот метод, но просто пропущу строки, где Person не изменится. – Ben

12

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

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: метод возвращает объект [], но массив заполняется экземплярами Person и экземплярами Person.

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

+0

То, что я ожидал, это список Person, а не список Object [] с дубликатами людей, когда они владеют более чем одной книгой. См. Мой ответ для ссылки на отчет об ошибке hibernate jira. – Ben

+0

Извините, чтобы я понял, метод возвращает Object [], но массив заполняется Person и только Person. У меня нет книг. –

1

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

33

Расширение ответа Мэтьюза. Чтобы заставить спящий режим только вернуть список лиц сделать:

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 книги лица будут извлекаться и инициализируется без дополнительного вызова БД.

Дубликат

.addEntity("p", Person.class) 

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

.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) 

работает на добавлен последний объект.

+1

Это позволит получить все для Person and Book. Что делать, если вы хотите выбрать только определенные свойства для повышения производительности. Как я понимаю, ничего, кроме * или p. *, Не работает. – T3rm1

+1

Использование '{p. *}, {B. *}' Также исправляет проблему дополнительных подзапросов для 'books'. –