111 votes

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

J'ai parcouru la section sur la génération d'Id du guide de référence Hibernate et "java persistence with Hibernate".

Il existe un certain nombre d'options disponibles avec Hibernate et JPA combinés.

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

Je suis également à la recherche de points de basculement.

Par exemple, la stratégie hilo est censée réduire la contention. Je suppose qu'il doit y avoir un compromis associé à ce choix.

Je veux être informé des avantages et des inconvénients.

Y a-t-il de la documentation disponible ?

97voto

ManuPK Points 5236

Le site Doc API sont très claires à ce sujet.

Tous les générateurs mettent en œuvre l'interface org.hibernate.id.IdentifierGenerator. Il s'agit d'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 raccourcis des générateurs intégrés sont les suivants :

incrémenter

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

identité

supporte les colonnes d'identité dans DB2, MySQL, MS SQL Server, Sybase et HypersonicSQL. L'identifiant retourné 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, étant donné une table et une colonne (par défaut hibernate_unique_key et next_hi respectivement) comme source de valeurs hi. L'algorithme hi/lo génère des identifiants qui ne sont uniques que 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, étant donné une séquence de base de données nommée.

uuid

utilise un algorithme UUID de 128 bits pour générer des identifiants de type chaîne de caractères qui sont uniques au sein d'un réseau (l'adresse IP est utilisée). L'UUID est codé comme une chaîne de 32 chiffres hexadécimaux.

guide

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

indigène

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

assigné

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

sélectionnez

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

étranger

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

séquence-identité

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 qui la combine avec JDBC3 getGeneratedKeys pour renvoyer la valeur d'identifiant générée dans le cadre de l'exécution de l'instruction d'insertion. Cette stratégie n'est prise en charge que par les pilotes Oracle 10g destinés au 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 opter pour incrément, identité, hilo etc. Ceux-ci sont simples à configurer et n'ont pas nécessité beaucoup de codage dans la base de données.

Vous devez choisir séquence ou guide en fonction de votre base de données. Celles-ci sont sûres et meilleures car le id se produira à l'intérieur de la base de données.

Mise à jour : Récemment, nous avons eu un problème avec l'idendité où le type primitif (int) a été corrigé en utilisant le type warapper (Integer) à la place.

59voto

Vlad Mihalcea Points 3628

En gros, vous avez deux grands choix :

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

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

  • Identifiants UUID.
  • Identifiants numériques.

Pour les identificateurs numériques, vous avez trois possibilités :

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

SEQUENCE est l'option préférée, surtout lorsqu'elle est utilisée avec un optimiseur d'identifiant comme pooled ou pooled-lo .

TABLE est à éviter car il utilise une transaction séparée pour récupérer l'identifiant et les verrous au niveau des lignes, ce qui n'est pas adapté.

20voto

Eyal Lupu Points 626

Il y a quelque temps, j'ai écrit un article détaillé sur les générateurs de clés 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 le faire le plus tôt possible - une migration tardive pourrait être un cauchemar.

C'est un peu hors sujet, mais c'est l'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 je dois communiquer mes objets avec d'autres systèmes, je n'expose pas ma clé (même si elle est de substitution) - j'utilise une "clé externe" supplémentaire. En tant que consultant, j'ai vu plus d'une fois de "superbes" intégrations de systèmes utilisant des clés d'objet (l'approche "c'est là, utilisons-le") pour découvrir un an ou deux plus tard que l'une des parties avait des problèmes avec la gamme de clés ou quelque chose du genre nécessitant une migration profonde du système exposant ses clés internes. Exposer votre clé signifie exposer un aspect fondamental de votre code à des contraintes externes auxquelles il ne devrait pas vraiment être exposé.

3voto

Adio Points 1712

Je trouve cette conférence très précieuse https://vimeo.com/190275665 Au point 3, il résume ces générateurs et donne également une analyse des performances et des conseils pour l'utilisation de chacun d'entre eux.

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