Je rencontre des problèmes pour représenter une hiérarchie d'objets dans Hibernate. J'ai cherché autour, et n'ai pas réussi à trouver des exemples faisant ceci ou semblable - vous avez mes excuses si ceci est une question commune.Représentation efficace des hiérarchies dans Hibernate
J'ai deux types que je voudrais persister en utilisant Hibernate: Groupes et Articles.
* Les groupes sont identifiés uniquement par une combinaison de leur nom et de leur parent.
* Les groupes sont organisés en un certain nombre d'arbres, de sorte que chaque groupe a zéro ou un groupe parent.
* Chaque élément peut appartenir à zéro ou plusieurs groupes.
Idéalement, je voudrais une relation bidirectionnelle me permettant d'obtenir:
* tous les groupes un élément est membre de
* tous les éléments qui sont membres d'un groupe particulier ou de ses descendants.
J'ai aussi besoin de pouvoir traverser l'arborescence du groupe depuis le haut pour l'afficher sur l'interface utilisateur.
La structure de l'objet de base ressemblerait idéalement comme ceci:
Au départ, je venais d'un simple bidirectionnel plusieurs à plusieurs entre les objets et les groupes, de sorte que la récupération tous les éléments d'une hiérarchie du groupe requis récursion l'arbre, et la récupération des groupes pour un élément a été un getter simple, à savoir:
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;
}
...
}
Cependant, cela a donné lieu à des demandes de plusieurs bases de données pour récupérer les éléments d'un groupe avec de nombreux descendants, ou pour récupérer le groupe entier arborescence à afficher dans l'interface utilisateur. Cela semble très inefficace, en particulier avec des arbres plus profonds et plus grands. Existe-t-il une meilleure façon de représenter cette relation dans Hibernate? Est-ce que je fais quelque chose de manifestement faux ou stupide?
Mon seul autre pensée à ce jour était la suivante: Remplacer id, les champs parents et le nom du groupe avec un « chemin » unique chaîne qui spécifie l'ensemble ascendance d'un groupe, par exemple:
/rootGroup
/rootGroup/unenfant
/rootGroup/unenfant/aGrandChild
La table de jointure entre les groupes et les objets contient alors group_path et item_id. Cela résout immédiatement les deux problèmes dont je souffrais auparavant:
1. La hiérarchie de groupe entière peut être extraite de la base de données dans une seule requête et reconstruite en mémoire.
2. Pour récupérer tous les éléments d'un groupe ou ses descendants, nous pouvons choisir parmi group_item où group_path = « N » ou group_path comme « N /% »
Cependant, cela semble vaincre le point d'utiliser Hibernate. Toutes les pensées sont les bienvenues
La maxime de Knuth «L'optimisation prématurée est-elle la racine de tout mal? –
Je suppose, comme dans plusieurs cas similaires, que ce n'est pas un problème de grandes structures de données en mémoire mais un nombre croissant d'opérations SQL. Bien que chaque opération soit très rapide, dans les réseaux d'objets complexes, le nombre de requêtes et le temps de latence de la communication feront descendre une application à l'analyse. Dans ce cas, je préfère normalement identifier des parties plus grandes du réseau et utiliser des techniques pour (pré) les récupérer le plus tôt possible (voir la réponse supplémentaire ci-dessous). La mémoire peut être réutilisée facilement. –
@ Matthew Oui, je crois qu'il a dit ça. @Ralf Nous n'avons tout simplement pas l'info. J'essaie juste de couvrir les deux bases. –