Hibernate: объединение двух объектов в один класс для получения данных с помощью одного запроса HQL.

У меня есть один такой класс:

public class BookAuthor {

  private Book book;
  private Author author;
}

Книга и Автор определяются как объекты.

Когда я пытаюсь получить данные, вот так:

final String selectCols = "NEW BookAuthor(b,a)";
final org.hibernate.Query q = createQuery(selectCols, params, filters);
result = q.list();
return result;

Когда Hibernate выполняет «q.list()», он выполняет один запрос для получения идентификаторов книги и автора, а затем повторяет результаты, чтобы получить информацию об авторах и книгах. То есть в моем логе было бы что-то вроде этого:

select a.ID, b.ID
from authors a , books b

И затем для каждой строки:

select a.ID, a.name
where a.ID = ?

select b.ID, b.title
where b.ID = ?

Есть ли способ сказать Hibernate, чтобы получить результаты с одним запросом, чтобы повысить производительность, как это? :

select a.ID, a.name, b.ID, b.title
from authors a , books b

Заранее спасибо.

Редактировать :

Сущности определяются со ссылкой на их таблицы и имена столбцов, например:

public static final String TABLE_NAME = "AUTHOR";
@Column(name = "id", nullable = false)
protected Long id;

Я думаю, что между автором и книгой нет ограничений БД (это был только пример реальных сущностей, но допустим, что могут быть некоторые анонимные книги без автора). Спасибо JB Nizet, я получу запрос и опубликую его здесь через некоторое время.


person krause    schedule 09.05.2013    source источник
comment
Как определяются сущности? Какой запрос вы выполняете? Почему бы вам просто не выбрать все книги или всех авторов и использовать связь между ними, чтобы получить автора (или книги)?   -  person JB Nizet    schedule 09.05.2013


Ответы (2)


Вы не должны рассматривать спящие запросы как SQL-запросы. Я предполагаю, что вам нужна ленивая загрузка в спящем режиме:

Если вы извлекаете BookAuthor, а свойства Book и Author загружены лениво, это будет медленным (поскольку спящий режим должен сделать всего 3 запроса для одного объекта)

Таким образом, в зависимости от вашей ситуации, вы можете отключить ленивую загрузку для вашего BookAuthor в вашем сопоставлении - тогда hibernate будет извлекать все данные в одном запросе выбора.

person IsNull    schedule 09.05.2013
comment
Я одобрил этот ответ, но, в конце концов, не смог заставить его работать с таким подходом к классу, содержащему две сущности. Я всегда выполнял много SQL-запросов. Я просто изменил оператор выбора на что-то вроде этого: выберите НОВУЮ карту (a.ID, a.name, b.ID, b.title), а затем сопоставьте результаты с атрибутами класса. Не элегантное решение, но, по крайней мере, оно сработало. - person krause; 13.05.2013

Обычно это происходит, когда вы хотите создать список элементов. В этом случае вы знаете, какие поля вас интересуют. Таким образом, вы указываете их в своей проекции (в SQL предложение SELECT).

Как вы предлагаете это делать, это нормально. Как только вы сопоставите отношения, Hibernate сделает это за одно соединение, потому что вы указываете список проекций.

Разница в том, что теперь вы получите список экземпляров Object[]. Hibernate оставит вам декомпозицию в сущности.

person carbontax    schedule 09.05.2013