Здесь есть несколько вопросов о запросах к отображенным таблицам HQL «многие ко многим», но я немного посмотрел и не видел этой.
У меня есть две таблицы в отношениях «многие ко многим» с исходными и целевыми таблицами, сопоставленными как сущности, и взаимосвязью @ManyToMany, определенной между ними, настроенной так, как это обычно рекомендуется.
Суть в том, что я пытаюсь выполнить запрос к этим таблицам, чтобы получить значения ключей источника и назначения в одном запросе. Причина в производительности: у нас есть глубоко вложенные иерархические данные, и для получения всех связанных с ними данных через ванильный Hibernate выдается десятки или сотни запросов, которые не выполняются должным образом. Вместо этого я намереваюсь извлечь все данные сразу и отобразить их в коде.
Вот примеры определений классов:
@Entity
public class This {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
@Column
protected Long otherId;
@ManyToMany
@JoinTable(joinColumns = {@JoinColumn(name = "this_id")},
inverseJoinColumns = {@JoinColumn(name = "that_id")})
private List<That> thats;
// getters and setters
}
и
@Entity
public class That {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name", unique = true)
private String name;
// getters and setters
}
HQL это:
select t.id,t.thats from This t where t.otherId=13
А вот SQL, который получается:
select
this0_.id as col_0_0_,
. as col_1_0_,
that2_.id as id1_59_,
that2_.name as name2_59_
from
this this0_
inner join
this_thats thats1_
on this0_.id=thats1_.this_id
inner join
that that2_
on thats1_.that_id=that2_.id
where
this0_.other_id=13
Как видите, 2-й столбец в предложении select
недопустим, он выглядит так, как будто пытается создать столбец, но не использует допустимое имя или псевдоним столбца и несколько неожиданно создает недопустимый оператор SQL синтаксис, который терпит неудачу, когда это выполнено. Я прошел через код генерации SQL и включил ведение журнала трассировки, но не могу понять, что он пытается сделать или как это исправить.
Если я удаляю второй столбец, этот запрос выполняется нормально и возвращает именно те данные, которые я ищу. В качестве альтернативы я рассмотрел реализацию этого в нативном SQL, но я бы хотел этого избежать и придерживаться HQL, если это возможно, для согласованности в остальной части проекта.
Другой вариант, который я пробовал, был select t,t.thats ...
. Это произвело действительный запрос, но, не показанный в этом примере, он выдал намного больше запросов для других отношений, которые охотно выбираются из сущности This
, что также снижает производительность. Мне действительно нужно выбрать только один ключевой столбец из исходной таблицы.
Действительно минимальный запрос, который бы возвращал нужные мне данные, вообще не должен был бы попадать в таблицу That
, он был бы только в таблице This
и неявной не отображенной таблице this_thats
, которая была создана и управляется JPA, но не отображается на объект. Я попытался сопоставить это с сущностью, чтобы я мог запросить его, но Hibernate пожаловался при запуске, что эта таблица была отображена дважды. Если есть какой-то другой способ добраться до этой таблицы и запросить ее напрямую, я был бы рад сделать это.
Это с hibernate-jpa-2.1, который, как я знаю, является старой версией, но это устаревшая система в производстве. Если бы обновление JPA помогло, я бы обдумал это, но сначала хотел бы понять причину, если это возможно.