2012-03-30 1 views
0

je par exemple, un DB avec l'entité suivante et la structure relation:Mise en veille prolongée - Limiter les collections de chargement désireux d'une table profonde

[personne] a beaucoup [compétences], [compétences] a beaucoup [Actions]

Dans les fichiers .hbm.xml, j'assigne des relations un-à-plusieurs pour la personne> compétences, compétences> actions.

Dans une requête, je voudrais être en mesure de contrôler quand je interroge sur la personne, pour charger impatiemment que les compétences. Actuellement, je semble être coincé là où je suis impatient de charger RIEN, et générer un nombre n + 1 de requêtes pour obtenir les compétences d'une personne, ou générer un nombre de requêtes (n * n + 1) car il charge avec impatience l'ensemble Personne> Compétences> Hiérarchie de collection d'actions.

Comment est-ce que je le limiterais de telle sorte que je peux contrôler quand je fais et ne veux pas charger la troisième table de profondeur? Pour le contexte, je serais capable de toujours avoir la collection Person> Skills initialisée, idéalement en tant que JOIN pour éviter les goulots d'étranglement de performance n + 1.

+0

Est-ce que vous ne pouvez pas simplement mettre des actions à charge paresseuse sur le mappage des compétences? L'appel à skills.getActions() obligera Hib à les récupérer quand vous en aurez besoin. Ou ai-je mal compris votre problème? – bvulaj

Répondre

0

Cela s'est avéré assez facile à contrôler à l'exécution.

Dans mon fichier .hbm.xml j'ai continué à déclarer mes jeux d'association comme paresseux, (encore plus paresseux!).

Dans la requête HQL, je requête comme:

Select distinct p from Person

left join fetch p.skills

les forces de mot-clé fetch chargement avide de ce particulier rejoindre.

0

J'utilise la pratique suivante:

J'essaie d'éviter des collections d'enfants sur les objets, en particulier si une collection enfant pourrait avoir un grand nombre d'entrées. Si j'ai besoin d'obtenir les enfants, j'utilise une requête pour les obtenir.

Si j'ai des collections enfants, je mets toujours les collections à la charge. Pour 'querying', en utilisant l'API Criteria, j'ai une classe qui crée la requête, l'exécute et retourne le résultat. Dans le cadre de la construction de la requête, j'utilise root.fetch(Person_.skills); où la racine est javax.persistence.criteria.Root<Person> pour charger avec impatience les collections que je veux.

+0

Je pensais aussi emprunter cette route, et je finirai probablement là-bas. Mais j'espérais qu'il y aurait une façon plus directe de dire à Hibernate "Initialiser les collections de l'objet racine, mais pas les collections de ces collections". D'une certaine manière dynamique. Mon application s'infiltre, donc j'ai seulement besoin d'accéder aux associations suivantes. – Eric

0

C'est un peu hors-sujet, mais vous pourriez envisager d'utiliser une implémentation de la base de données graphique pour maintenir les données de ce niveau de complexité au lieu de RDBMS et Hiberante. Voir neo4j, la base de données graphique, qui permet de créer des nœuds (dans votre cas, des personnes, des compétences) et des relations entre eux (étend, sait). Ainsi, vous serez en mesure de traverser facilement une donnée à n'importe quel niveau de profondeur.

Questions connexes