У меня возникли проблемы с представлением иерархии объектов в Hibernate. Я искал вокруг, и не смог найти ни одного примера, делающего это или подобное - у вас есть мои извинения, если это общий вопрос.
У меня есть два типа, которые я бы хотел сохранить в Hibernate: группы и элементы.
* Группы идентифицируются уникальным образом по комбинации их имени и родителя.
* Группы расположены в несколько деревьев, так что каждая группа имеет ноль или одну родительскую группу.
* Каждый элемент может быть членом нуля или более групп.
В идеале, я бы хотел двунаправленных отношений, позволяющих мне получить:
* все группы, в которые входит элемент
* все предметы, которые являются членами определенной группы или ее потомков.
Мне также нужно иметь возможность просматривать дерево групп сверху, чтобы отобразить его в пользовательском интерфейсе.
В идеале базовая структура объекта будет выглядеть так:
class Group {
...
/** @return all items in this group and its descendants */
Set<Item> getAllItems() { ... }
/** @return all direct children of this group */
Set<Group> getChildren() { ... }
...
}
class Item {
...
/** @return all groups that this Item is a direct member of */
Set<Group> getGroups() { ... }
...
}
Первоначально я только что установил простое двунаправленное отношение «многие ко многим» между Предметами и Группами, чтобы выборка всех элементов в иерархии групп требовала рекурсии вниз по дереву, а выборка групп для Предмета была простым средством получения. , т.е.:
class Group {
...
private Set<Item> items;
private Set<Group> children;
...
/** @return all items in this group and its descendants */
Set<Item> getAllItems() {
Set<Item> allItems = new HashSet<Item>();
allItems.addAll(this.items);
for(Group child : this.getChildren()) {
allItems.addAll(child.getAllItems());
}
return allItems;
}
/** @return all direct children of this group */
Set<Group> getChildren() {
return this.children;
}
...
}
class Item {
...
private Set<Group> groups;
/** @return all groups that this Item is a direct member of */
Set<Group> getGroups() {
return this.groups;
}
...
}
Однако это привело к нескольким запросам базы данных для выборки элементов в группе со многими потомками или для получения всего дерева групп для отображения в пользовательском интерфейсе. Это кажется очень неэффективным, особенно с более глубокими, большими групповыми деревьями.
Есть ли лучший или стандартный способ представления этих отношений в Hibernate?
Я что-то делаю явно неправильно или глупо?
<Ч />
Моя единственная другая мысль до сих пор была такая:
Замените поля id, parent и name группы уникальной строкой «path», которая указывает всю родословную группы, например ::
/ RootGroup
/ RootGroup / aChild
/ rootGroup / aChild / aGrandChild
Таблица объединения между группами и элементами будет содержать group_path и item_id.
Это сразу решает две проблемы, с которыми я страдал ранее:
1. Вся иерархия групп может быть извлечена из базы данных в одном запросе и восстановлена в памяти.
2. Чтобы получить все элементы в группе или ее потомках, мы можем выбрать из group_item, где group_path = 'N' или group_path, например 'N /%'
Однако это, похоже, лишает смысла использование Hibernate. Все мысли приветствуются!