В приложении Hibernate, над которым я работаю, есть таблица с иерархическими данными (Oracle Database).
Для простоты я приведу пример человека с отцом (предположим, чтоиерархия не является фиксированной и может варьироваться для более чем 3 уровней).
Каждый человек может иметь автомобиль (может быть, пару автомобилей).
@Entity
class Person
{
@Id
private String id;
@ManyToOne
@JoinColumn(name = "FATHER_ID")
private Person father;
}
@Entity
class Car
{
@Id
private String id;
@ManyToOne
private Person owner;
}
До сих пор, когда нам нужно было получитьвсе машины для потомков человека, мы создали собственный запрос, извлекающий идентификаторы всех потомков, а затем второй hql-запрос для извлечения самих автомобилей (используя предложение IN с ранее выбранными идентификаторами в качестве параметров привязки).
Я надеваюнам это не нравится, потому что он окрашивает наш код и заставляет нас выдавать больше запросов, чем нам нужно.
Более того, мы немного злоупотребляем предложением IN, используя другое количество параметров связывания для многих наших запросов..
Поэтому я решил попытаться инкапсулировать эти иерархические данные, используя Hibernate.
Я пытался использовать @JoinFormula, чтобы получить ответ человекаndants как элемент данных, подобный этому:
@Entity
class Person
{
...
@JoinFormula(value = "SELECT p.id FROM Person p START WITH p.id = id CONNECT BY PRIOR p.id = father_id", referencedColumnName = "id")
@OneToMany
List<Person> descendants;
}
К сожалению, это не работает, hibernate выдает исключение:
ClassCastException: org.hibernate.mapping.Formula cannot be cast to org.hibernate.mapping.Column
Я попытался изменить отношение к @ManyToMany, оно исправляетClassCastException, но затем hibernate просто игнорирует формулу и создает новую таблицу.
Сейчас я думаю об использовании функции sql для получения идентификаторов потомков и использовании ее внутри моего hql.Однако я не совсем уверен, как это сделать ...
Любая помощь будет высоко ценится!