80 votes

Quel type de 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 existait des règles de base en la matière.

MISE À JOUR Je sais faire la différence entre un Set et un List . A List autorise les doublons et dispose d'un ordre et d'une Set ne peut pas contenir d'éléments en double et ne définit pas d'ordre. Je pose cette question dans le contexte de JPA. Si vous suivez strictement la définition, vous devriez toujours finir par utiliser l'élément Set puisque votre collection est stockée dans une base de données relationnelle, où vous ne pouvez pas avoir de doublons et où vous devez définir un ordre par vous-même, c'est-à-dire l'ordre dans votre base de données Java List n'est pas nécessairement conservée dans la base de données.

Par exemple, la plupart du temps, j'utilise la fonction List non pas parce qu'il a un ordre ou autorise les doublons (que je ne peux pas avoir de toute façon), mais parce que certains des composants de ma bibliothèque de composants ont besoin d'une liste.

0 votes

Je pense que vous trouverez l'annotation @OrderBy utile et intéressante. Premier lien de Google à ce sujet : objectdb.com/api/java/jpa/OrderBy

0 votes

@Grzegorz Oledzki Je connais la @OrderBy mais cela n'a rien à voir avec l'ordre dans votre List . Si vous récupérez votre liste d'entités (qui est annotée avec la mention @OrderBy ), modifie son ordre, fusionne avec la base de données et le récupère à nouveau, l'ordre que vous avez modifié sera-t-il préservé ? Non ! Vous obtiendrez le même ordre que celui que vous avez défini via @OrderBy

0 votes

Je suis d'accord pour dire que ce serait formidable. Mais vous êtes à mi-chemin. Lorsque vous lirez une telle entité, vous obtiendrez l'ordre approprié.

56voto

Konrad Garus Points 19280

Comme le suggère votre propre question, la clé est le domaine, pas JPA . JPA n'est qu'un cadre que vous pouvez (et devez) utiliser de la manière la plus adaptée à votre problème. Le choix d'une solution sous-optimale à cause d'un cadre (ou de ses limites) est généralement une sonnette d'alarme.

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

Vous semblez bien connaître la différence entre Collection , Set y List . La seule raison d'utiliser l'un ou l'autre dépend uniquement de vos besoins. Vous pouvez les utiliser pour communiquer aux utilisateurs de votre API (ou à votre futur utilisateur) les propriétés de votre collection (qui peut être subtile ou implicite).

Cela suit exactement les mêmes règles que l'utilisation de différents types de collection partout ailleurs dans votre code. Vous pourriez utiliser Object o Collections pour toutes vos références, mais dans la plupart des cas, vous utilisez des types plus concrets.

Par exemple, lorsque je vois un List Je sais qu'il est trié d'une manière ou d'une autre et que les doublons sont soit acceptables, soit non pertinents dans ce cas. Lorsque je vois un Set je m'attends généralement à ce qu'il n'y ait pas de doublons et à ce qu'il n'y ait pas d'ordre spécifique (à moins qu'il ne s'agisse d'un SortedSet ). Lorsque je vois un Collection Je n'en attends rien de plus que de contenir quelques entités.

En ce qui concerne l'ordonnancement des listes... Oui, il peut être préservé. Et même si ce n'est pas le cas et que vous utilisez simplement @OrderBy mais il peut toujours être utile. Pensez à l'exemple du journal des événements trié par défaut selon l'horodatage. Réorganiser artificiellement la liste n'a guère de sens, mais il peut tout de même être utile qu'elle soit triée par défaut.

1 votes

Ne devriez-vous pas finir par toujours utiliser Set alors ? Parce que vous stockez vos entités dans une base de données relationnelle, où il ne peut y avoir d'éléments dupliqués et où vous devez définir un ordre par vous-même (c'est-à-dire l'ordre dans votre Java List n'est pas préservé lorsqu'il est maintenu). Et quand utilisez-vous Collection ?

1 votes

Si nécessaire, vous pouvez persister List commander en utilisant un champ artificiel. Dans la plupart des cas, cependant, il est naturel. Un exemple peut être une sorte de journal basé sur le temps, où vous pouvez utiliser @OrderBy("eventDate"). Quant à Collection Je l'utiliserais dans des situations similaires à Set .

0 votes

Oui, vous pouvez utiliser une colonne d'index ou la fonction @OrderBy mais cet ordre spécifié par ces moyens n'est pas lié à l'ordre de votre liste Java. Vous pouvez également utiliser l'annotation @OrderBy sur un Set ou utiliser une colonne d'index. Et si vous changez l'ordre dans votre liste java, l'ordre dans la base de données ne sera pas reflété dans la base de données.

49voto

u_b Points 129

La question de l'utilisation d'un ensemble ou d'une liste est beaucoup plus difficile, je pense. Au moins lorsque vous utilisez hiberner en tant qu'implémentation de JPA. Si vous utilisez une liste dans hibernate, il bascule automatiquement vers le format "Sacs" où des doublons PEUVENT exister.

Et cette décision a une influence significative sur les requêtes exécutées par hibernate. Voici un petit exemple :

Il existe deux entités, employé y entreprise Pour mettre en correspondance ces entités, il existe une table commune (appelons-la "employeeCompany").

Vous choisissez le type de données Liste sur les deux entités (entreprise/salarié)

Si vous décidez maintenant de supprimer Employé Joe de EntrepriseXY hibernate 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 Hibernate n'exécute-t-il pas seulement cette requête ?

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

La réponse est simple (et merci beaucoup à Nirav Assar pour son article de blog) : Il ne peut pas . Dans un monde de sacs, supprimer tout et réinsérer tout ce qui reste est la seule façon de procéder ! Lisez ceci pour plus de clarté. http://assarconsulting.blogspot.fr/2009/08/why-hibernate-does-delete-all-then-re.html

Et maintenant, la grande conclusion :

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

Et pourquoi cela ? Parce qu'hibernate n'est plus dans un monde de sacs (comme vous le savez, Sets n'autorise pas les doublons) et qu'exécuter une seule requête est désormais possible.

Le choix entre les listes et les ensembles n'est donc pas si simple, du moins en ce qui concerne les requêtes et les performances !

9voto

James Points 18355

J'utilise généralement un List . Je trouve l'API Liste bien plus utile et compatible avec d'autres bibliothèques que l'API Set . La liste est plus facile à itérer 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 qu'elle 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. S'il s'agit d'un objet sur lequel vous allez effectuer de nombreuses vérifications de contenu, alors un Set serait plus efficace.

Vous pouvez ordonner une relation dans JPA, soit en utilisant un @OrderBy ou 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 mappings tels que ElementCollections peut prendre en charge des doublons.

4voto

Ralph Points 42744

J'utilise :

  • Ensemble : lorsque les éléments de la collection ne sont pas ordonnés et sont uniques.
  • Liste : lorsque les éléments ont un ordre

2 votes

Ne devriez-vous pas finir par toujours utiliser Set ? Parce que vous stockez vos entités dans une base de données relationnelle, où il ne peut y avoir d'éléments en double et où vous devez définir vous-même un ordre (c'est-à-dire que l'ordre de votre liste Java n'est pas préservé lorsqu'elle est persistée). Et quand utilise-t-on Collection ?

1 votes

Que voulez-vous dire par can't be any duplicate elements ? Bien sûr que oui. Il suffit d'avoir une clé primaire comme champ Id, et le reste peut être dupliqué.

1 votes

Theo L'égalité des objets repose sur la méthode equals. L'égalité dans les bases de données repose uniquement sur la (les) clé(s) primaire(s). Ce ne sont pas nécessairement les mêmes.

1voto

AmanicA Points 1996

Je pense que l'utilisation de Collection comme valeur générique par défaut 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 modifier et rester compatible avec le passé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X