web-dev-qa-db-fra.com

Quel type Java utilisez-vous pour les collections JPA et pourquoi?

Lequel des types de collection suivants utilisez-vous dans votre modèle de domaine JPA et pourquoi:

  • Java.util.Collection
  • Java.util.List
  • Java.util.Set

Je me demandais s'il y avait des règles de base pour cela.

UPDATE Je connais la différence entre un Set et un List. Un List autorise les doublons et a un ordre et un Set ne peut pas contenir d'éléments en double et ne définit pas l'ordre. Je pose cette question dans le contexte de l'APP. Si vous suivez strictement la définition, vous devez toujours utiliser le type Set, car votre collection est stockée dans une base de données relationnelle, où vous ne pouvez pas avoir de doublons et où vous avez défini une commande par vous-même, c'est-à-dire l'ordre en vous Java List n'est pas nécessairement conservé dans la base de données.

Par exemple, la plupart du temps j'utilise le type List, non pas parce qu'il a une commande ou autorise les doublons (ce que je ne peux pas avoir de toute façon), car certains des composants de ma bibliothèque de composants nécessitent un liste.

54
Theo

Comme le suggère votre propre question, la clé est le domaine, pas JPA. JPA n'est qu'un cadre que vous pouvez (et devriez) utiliser de la manière qui convient le mieux à votre problème. Le choix d'une solution sous-optimale en raison du cadre (ou de ses limites) est généralement un signal d'alarme.

Lorsque j'ai besoin d'un ensemble et que je ne me soucie jamais de la commande, j'utilise un Set. Lorsque, pour une raison quelconque, l'ordre est important (liste ordonnée, classement par date, etc.), alors un List.

Vous semblez bien conscient de la différence entre Collection, Set et List. La seule raison d'utiliser l'un contre l'autre ne dépend que de vos besoins. Vous pouvez les utiliser pour communiquer aux utilisateurs de votre API (ou votre futur moi-même) les propriétés de votre collection (qui peuvent être subtiles ou implicites).

Ceci suit exactement les mêmes règles que l'utilisation de différents types de collections n'importe où ailleurs dans votre code. Vous pouvez utiliser Object ou Collections pour toutes vos références, mais dans la plupart des cas, vous utilisez des types plus concrets.

Par exemple, quand je vois un List, je sais qu'il est trié d'une certaine manière et que les doublons sont acceptables ou non pertinents dans ce cas. Quand je vois un Set, je m'attends généralement à ce qu'il n'y ait pas de doublons et pas d'ordre spécifique (sauf s'il s'agit d'un SortedSet). Quand je vois un Collection, je n'en attends rien de plus que de contenir des entités.

Concernant l'ordre des listes ... Oui, il peut être conservé. Et même si ce n'est pas le cas et que vous utilisez simplement @OrderBy, cela peut encore être utile. Pensez à l'exemple du journal des événements trié par horodatage par défaut. Réorganiser artificiellement la liste n'a pas de sens, mais il peut être utile qu'elle soit triée par défaut.

46
Konrad Garus

La question de l'utilisation d'un ensemble ou d'une liste est beaucoup plus difficile, je pense. Au moins lorsque vous utilisez hibernate comme implémentation JPA. Si vous utilisez une liste en veille prolongée, elle bascule automatiquement vers le paradigme "Sacs" , où des doublons PEUVENT exister.

Et cette décision a une influence significative sur les requêtes mises en veille prolongée. Voici un petit exemple:

Il y a deux entités, employé et entreprise , un nombre -beaucoup de relations. pour mapper ces entités les unes aux autres, il existe une JoinTable (appelons-la "employeeCompany").

Vous choisissez la liste de types de données sur les deux entités (société/employé)

Donc, si vous décidez maintenant de supprimer Employee Joe from CompanyXY, hibernate s'exécute les requêtes suivantes:

delete from employeeCompany where employeeId = Joe;
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXA);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXB);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXC);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXD);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXE);

Et maintenant, la question: pourquoi diable hiberne non seulement exécuter cette requête?

delete from employeeCompany where employeeId = Joe AND company = companyXY;

La réponse est simple (et merci beaucoup à Nirav Assar pour son blog): Ça ne peut pas . Dans un monde de sacs, tout supprimer et réinsérer tout ce qui reste est le seul moyen approprié! Lisez cela pour plus de précisions. http://assarconsulting.blogspot.fr/2009/08/why-hibernate-does-delete-all-then-re.html

Maintenant, la grande conclusion:

Si vous choisissez un ensemble au lieu d'une liste dans votre employé/entreprise - entités, vous n'avez pas ce problème et une seule requête est exécutée!

Et pourquoi ça? Parce que l'hibernation n'est plus dans un monde de sacs (comme vous le savez, Sets n'autorise aucun doublon) et l'exécution d'une seule requête est désormais possible.

La décision entre la liste et les ensembles n'est donc pas si simple, du moins en ce qui concerne les requêtes et les performances!

28
u_b

J'utilise généralement une liste. Je trouve l'API List beaucoup plus utile et compatible avec d'autres bibliothèques que Set. La liste est plus facile à parcourir et généralement plus efficace pour la plupart des opérations et de la mémoire.

Le fait qu'une relation ne puisse pas avoir de doublons et ne soit pas normalement ordonnée ne devrait pas nécessiter l'utilisation d'un ensemble, vous pouvez utiliser le type de collection le plus utile à votre application.

Cela dépend de votre modèle, si c'est quelque chose sur lequel vous allez faire beaucoup de contrôles, alors un ensemble serait plus efficace.

Vous pouvez commander une relation dans JPA, à l'aide d'un @OrderBy ou d'un @OrderColumn.

Voir, http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Ordering

Les doublons ne sont généralement pas pris en charge dans JPA, mais certains mappages tels que ElementCollections peuvent prendre en charge les doublons.

7
James

J'utilise:

  • Ensemble: lorsque les articles des collections n'ont pas de commande et sont uniques
  • Liste: lorsque les articles ont une commande
3
Ralph

Je pense que l'utilisation de Collection comme valeur par défaut générique lors de la génération d'entités avec Netbeans est un bon point de départ, puis lorsque vous comprenez ce qu'est réellement votre modèle et que vous avez besoin de plus de fonctionnalités, vous pouvez facilement le changer et rester rétrocompatible.

0
AmanicA