L'utilisation de la séquence PostgreSQL en hibernation n'affecte pas le tableau des séquences

J'ai configuré Hibernate pour utiliser la séquence PostgreSQL (via les annotations) pour générer des valeurs pour la clé primaire id colonne comme suit:

@Id 
@SequenceGenerator(name="pk_sequence",sequenceName="entity_id_seq")
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="pk_sequence")
@Column(name="id", unique=true, nullable=false)
public int getId() {
    return this.id;
}

Ce que je vois avec cette configuration hibernate est déjà affectation id valeurs > 3000 sur la persistance, alors que la requête sur la séquence montre l'exemple suivant:

database=# select last_value from entity_id_seq;
last_value 
------------
     69

(1 rangée)

Questions:

Il n'y a rien de mal ou pas?

Devrait la synchronisation de l'hibernation avec la table de séquence?

Si ce n'est pas le cas, où stocke-t-il le dernier identifiant généré?

je vous Remercie.

24
demandé sur forker 2010-11-27 00:51:34

4 réponses

j'ai eu le même problème. Elle est liée aux stratégies d'allocation de l'hibernation. Whe n vous choisissez Générationtype.Séquence, Hibernate utilise la stratégie de HiLo qui attribue des ID en blocs de 50 par défaut. Ainsi, vous pouvez définir explicitement allocationSize valeur comme ceci:

@Id 
@SequenceGenerator(name="pk_sequence",sequenceName="entity_id_seq", allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="pk_sequence")
@Column(name="id", unique=true, nullable=false)
public int getId() {
    return this.id;
}

cependant, j'ai aussi entendu des opinions qui utilisent la stratégie de HiLo avec allocationSize=1 n'est pas une bonne pratique. Certaines personnes recommandent d'utiliser Générationtype.AUTO à la place, lorsque vous avez affaire à des séquences gérées par une base de données

mise à Jour: j'ai fini par aller avec allocationSize=1, et les choses semblent fonctionner comme je m'attendre maintenant. Mon application est telle que je n'ai pas vraiment besoin de blocs D'IDs de toute façon, donc YMMV.

28
répondu Nofate 2011-02-03 22:04:45

NE PAS utiliser GenerationType.Séquence pour les séquences Postgres!

C'est complètement contre-intuitif, mais l'Hibernation des gens complètement foiré sur ce. Vous doit utiliser GenerationType.AUTOdémolir vos séquences si vous devez redémarrer/reconstruire votre base de données. C'est presque une négligence criminelle qu'ils laissent ce code entrer dans une construction de production, mais l'équipe D'hibernation est plutôt célèbre pour leur tête de mule positions vers des positions totalement erronées (vérifiez leur position sur les joints de gauche, par exemple).

23
répondu Matt Brock 2010-12-21 17:21:33

tout d'abord, vous devez déterminer quelle version D'hibernation vous utilisez. En termes de versions Hibernate-core, 3.2 onwards a introduit un support plus cohérent pour les générateurs d'id, notamment en ce qui concerne défini dans les annotations. Voir http://in.relation.to/Bloggers/New323HibernateIdentifierGenerators pour une discussion.

suivant 3.6 introduit un cadre ('hibernation.id.new_generator_mappings') qui rend les générateurs discutés dans ce blog la manière par défaut Les annotations JPA sont traitées. Le paramètre est false par défaut car Hibernate doit maintenir une compatibilité ascendante avec les versions plus anciennes. Si vous voulez le nouveau comportement (qui est complètement recommandé) alors il suffit de mettre ce paramètre à true.

comment GenerationType est manipulé dépend de la version que vous utilisez et si vous avez hiberné.id.new_generator_mappings est défini à true. Je suppose que vous utilisez 3.6+ (puisque tout ce qui est plus vieux est, bien, vieux) et ont hibernation.id.la valeur de true de new_generator_mappings (puisque c'est la recommandation pour les nouvelles applications):

  1. GenerationType.AUTO - > traité comme GenerationType.Séquence
  2. GenerationType.SEQUENCE - > maps to the org.hibernation.id.amélioré.SequenceStyleGenerator class discuté dans le blog
  3. GenerationType.TABLE - > maps to the org.hibernation.id.amélioré.Classe de TableGenerator discuté dans le blog
7
répondu Steve Ebersole 2011-12-05 20:36:06

Dans Postgres, je ferais ceci:

@Id 
@SequenceGenerator(name="pk_sequence",sequenceName="\"entity_id_seq\"")
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="\"pk_sequence\"")
@Column(name="\"id\"", unique=true)
private int id;

La plupart du temps avec des noms en majuscules hibernent besoin de passer des citations échappées afin de comprendre les Postgres et de trouver les tables, les colonnes ou les noms de séquences.

0
répondu Christian Vielma 2012-10-03 15:43:09