web-dev-qa-db-fra.com

Comment choisir la stratégie de génération d'identifiants lors de l'utilisation de JPA et Hibernate

Je parcourais la section relative à la génération d'identifiants du guide de référence d'Hibernate et la "persistance de Java avec Hibernate"

Hibernate et JPA combinés offrent de nombreuses options.

Je cherchais une documentation supplémentaire sur la manière de choisir la stratégie de génération d'identifiant spécifique.

Je cherche aussi des points de basculement.

Par exemple, la stratégie hilo devrait permettre de réduire les conflits. Je suppose qu'il doit y avoir un compromis associé à ce choix.

Je veux être renseigné sur les compromis.

Y a-t-il de la littérature disponible?

101
user1317764

Les API Doc sont très clairs à ce sujet.

Tous les générateurs implémentent l'interface org.hibernate.id.IdentifierGenerator. C'est une interface très simple. Certaines applications peuvent choisir de fournir leurs propres implémentations spécialisées. Cependant, Hibernate fournit une gamme d’implémentations intégrées. Les noms de raccourci pour les générateurs intégrés sont les suivants:

incrémenter

génère des identificateurs de type long, short ou int qui ne sont uniques que lorsqu'un autre processus n'insère pas de données dans la même table. Ne pas utiliser dans un cluster.

identité

prend en charge les colonnes d’identité dans DB2, MySQL, MS SQL Server, Sybase et HypersonicSQL. L'identifiant renvoyé est de type long, short ou int.

séquence

utilise une séquence dans DB2, PostgreSQL, Oracle, SAP DB, McKoi ou un générateur dans Interbase. L'identifiant retourné est de type long, short ou int

hilo

utilise un algorithme hi/lo pour générer efficacement des identifiants de type long, short ou int, à partir d'une table et d'une colonne (respectivement, par défaut, hibernate_unique_key et next_hi) en tant que source de valeurs hi. L'algorithme hi/lo génère des identifiants uniques pour une base de données particulière.

seqhilo

utilise un algorithme hi/lo pour générer efficacement des identifiants de type long, short ou int, à partir d'une séquence de base de données nommée.

uuid

utilise un algorithme UUID de 128 bits pour générer des identificateurs de type chaîne uniques au sein d'un réseau (l'adresse IP est utilisée). L'UUID est codé sous la forme d'une chaîne de 32 chiffres hexadécimaux.

guid

utilise une chaîne GUID générée par la base de données sur MS SQL Server et MySQL.

natif

sélectionne identité, séquence ou hilo en fonction des capacités de la base de données sous-jacente.

attribué

permet à l'application d'attribuer un identifiant à l'objet avant que save () ne soit appelé. C'est la stratégie par défaut si aucun élément n'est spécifié.

sélectionnez

récupère une clé primaire, assignée par un déclencheur de base de données, en sélectionnant la ligne à l'aide d'une clé unique et en récupérant la valeur de la clé primaire.

étranger

utilise l'identifiant d'un autre objet associé. Il est généralement utilisé en association avec une association de clé primaire.

sequence-identity

une stratégie de génération de séquence spécialisée qui utilise une séquence de base de données pour la génération de la valeur réelle, mais combine cela avec JDBC3 getGeneratedKeys pour renvoyer la valeur de l'identificateur généré dans le cadre de l'exécution de l'instruction insert. Cette stratégie est uniquement prise en charge sur les pilotes Oracle 10g ciblés pour JDK 1.4. Les commentaires sur ces instructions d'insertion sont désactivés en raison d'un bogue dans les pilotes Oracle.

Si vous construisez une application simple avec peu d'utilisateurs simultanés, vous pouvez choisir incrément, identité, hilo , etc. Ils sont simples à configurer. pas besoin de beaucoup de codage à l'intérieur de la base de données.

Vous devez choisir la séquence ou guid en fonction de votre base de données. Celles-ci sont sûres et meilleures car la génération id aura lieu dans la base de données.

Mise à jour: Nous avons récemment eu un problème avec idendity où le type primitif (int) a été corrigé en utilisant le type warapper (Integer) à la place.

89
ManuPK

En gros, vous avez deux choix principaux:

  • Vous pouvez générer l'identifiant vous-même, auquel cas vous pouvez utiliser un identifiant attribué .
  • Vous pouvez utiliser l'annotation @GeneratedValue et Hibernate attribuera l'identifiant pour vous.

Pour les identificateurs générés, vous avez deux options:

Pour les identificateurs numériques vous avez trois options :

  • IDENTITÉ
  • SÉQUENCE
  • TABLE

IDENTITY n’est un bon choix que lorsque vous ne pouvez pas utiliser SEQUENCE (par exemple, MySQL) car cela désactive les mises à jour par lots JDBC .

SEQUENCE est l'option privilégiée, en particulier lorsqu'il est utilisé avec un optimiseur d'identificateur tel que pooled ou pooled-lo .

TABLE doit être évité à tout prix car il utilise une transaction distincte pour extraire l'identificateur et les verrous au niveau de la ligne qui évoluent mal.

44
Vlad Mihalcea


Il y a quelque temps, j'ai écrit un article détaillé sur les générateurs de clé d'Hibernate: http://blog.eyallupu.com/2011/01/hibernatejpa-identity-generators.html

Choisir le bon générateur est une tâche compliquée, mais il est important d'essayer de bien le faire dès que possible - une migration tardive peut être un cauchemar.

Un peu hors sujet, mais une bonne occasion de soulever un point généralement négligé, à savoir le partage des clés entre les applications (via l'API). Personnellement, je préfère toujours les clés de substitution et si j’ai besoin de communiquer mes objets avec d’autres systèmes, je n’expose pas ma clé (même s’il s’agit d’une clé de substitution). J’utilise une "clé externe" supplémentaire. En tant que consultant, j’ai vu plus d’une fois de "formidables" intégrations de systèmes utilisant des clés d’objet (l’approche "il suffit de l’utiliser") pour trouver un ou deux ans plus tard qu’un côté a des problèmes avec la plage de clés ou quelque chose du genre. le genre nécessitant une migration profonde sur le système exposant ses clés internes. Exposer votre clé, c’est exposer un aspect fondamental de votre code à des contraintes externes.

20
Eyal Lupu

Je trouve cette conférence très utile https://vimeo.com/190275665 . Au point 3, elle récapitule ces générateurs et fournit également une analyse des performances et une ligne directrice lorsque vous les utilisez.

2
Adelin