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

je passais en revue la section sur la génération D'Id du Guide de référence sur L'hibernation et" java persistence with Hibernate "

il y a plusieurs options disponibles avec Hibernate et JPA combiné.

j'étais à la recherche d'une documentation supplémentaire sur la façon de choisir la stratégie spécifique de génération d'id.

je cherche aussi des points de basculement.

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

je veux être instruit sur les compromis.

y a-t-il de la documentation disponible?

94
demandé sur Vlad Mihalcea 2012-04-06 13:58:52

4 réponses

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

tous les générateurs implémentent l'interface org.hibernation.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'aucun autre processus n'insère de données dans le même tableau. Ne pas utiliser dans un cluster.

identité

supporte les colonnes d'identité dans DB2, MySQL, MS SQL Server, Sybase et HypersonicSQL. L'identificateur 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'identificateur retourné est de type long, short ou int

hilo

utilise un algorithme hi/lo pour générer efficacement des identificateurs de type long, short ou int, à partir d'une table et d'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 uniques seulement pour une base de données particulière.

seqhilo

utilise un algorithme hi/lo pour générer efficacement des identificateurs de type long, court 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 chaîne de type qui sont uniques au sein d'un réseau (l'adresse IP est utilisé). L'UUID est codé comme une chaîne de 32 chiffres hexadécimaux de longueur.

guid

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

native

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 de l'enregistrer() est appelée. C'est la stratégie par défaut si aucun élément n'est spécifié.

sélectionner

récupère une clé primaire, assigné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'identificateur d'un autre objet associé. Il est généralement utilisé en conjonction avec une association 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 valeur réelle, mais qui la combine avec getGeneratedKeys JDBC3 pour retourner la valeur d'identification générée dans le cadre de l'exécution de l'instruction insert. Cette stratégie n'est soutenue que sur Pilotes Oracle 10g ciblés pour JDK 1.4. Les commentaires sur ces instructions insert sont désactivés en raison d'un bug dans les pilotes Oracle.

si vous construisez une application simple avec peu d'utilisateurs concurrents, vous pouvez aller pour incrément, identité, hilo etc.. Ceux-ci sont simples à configurer et n'ont pas besoin de beaucoup de codage à l'intérieur de la base de données.

vous devez choisir sequence ou guid selon votre base de données. Ceux-ci sont sûrs et meilleurs parce que la génération id se produira à l'intérieur de la base de données.

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

86
répondu ManuPK 2014-07-21 09:01:09

en gros, vous avez deux choix principaux:

  • vous pouvez générer vous-même l'identificateur, auquel cas vous pouvez utiliser un identificateur attribué .
  • vous pouvez utiliser l'annotation @GeneratedValue et Hibernate assignera l'identificateur 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

l'IDENTITÉ n'est un bon choix lorsque vous ne pouvez pas utiliser la SÉQUENCE (par exemple MySQL), parce que il désactive JDBC mises à jour par lot .

La séquence

est l'option préférée, en particulier lorsqu'elle est utilisée avec un optimiseur d'identificateur comme pooled or pooled-lo .

La TABLE

doit être évitée à tout prix car elle utilise une transaction séparée pour récupérer l'identificateur et les serrures au niveau de la rangée qui se balance mal.

36
répondu Vlad Mihalcea 2018-01-04 09:06:12



Il y a peu, 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 correctement dès que possible - une migration tardive pourrait être un cauchemar.



Un peu hors sujet, mais une bonne occasion de soulever un point habituellement négligé qui est le partage des clés entre les applications (via 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 si c'est une clé de substitution) – j'utilise une "clé externe" supplémentaire. En tant que consultant, j'ai vu plus d'une fois de "grandes" intégrations de systèmes utilisant des clés objet (l'approche "it is there let's just use it") juste pour trouver un an ou deux plus tard qu'un côté a des problèmes avec la gamme de clés ou quelque chose du genre qui nécessite une migration profonde sur le système exposant ses clés internes. Exposer votre clé signifie exposer un aspect fondamental de votre code à des contraintes externes ne devrait pas vraiment être exposé.

19
répondu Eyal Lupu 2012-11-03 09:09:54

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 de performance et la ligne directrice Un lorsque vous utilisez chacun d'eux.

2
répondu Adelin 2017-02-06 21:14:51