Question

I ai configuré pour utiliser Hibernate séquence PostgreSQL (via annotations) pour générer des valeurs de 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 est que mise en veille prolongée est déjà id valeurs> 3000 sur la persistance, alors que la requête sur séquence utilisée affiche les éléments suivants:

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

(1 rang)

Questions:
Y at-il quelque chose de mal ou non?
Mise en veille prolongée doit synchroniser avec la table de séquence
Sinon, où est-il stocke le dernier identifiant généré?

Merci.

Était-ce utile?

La solution

J'ai eu le même problème. Elle est liée à l'id allouer des stratégies de mise en veille prolongée. Whe n vous choisissez GenerationType.SEQUENCE , Hibernate utilise la stratégie HiLo qui attribue les ID dans les 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;
}

Bien, je l'ai aussi entendu des opinions que l'utilisation de la stratégie HiLo avec allocationSize = 1 est pas une bonne pratique. Certaines personnes recommandent d'utiliser GenerationType.AUTO au lieu quand vous avez à traiter avec des séquences gérées bases de données

Mise à jour: J'ai fini par aller avec allocationSize = 1, et les choses semblent fonctionner comme je l'attends maintenant. Ma demande est telle que je ne ai pas vraiment besoin de blocs d'ID de toute façon, YMMV.

Autres conseils

NE PAS UTILISER GenerationType.SEQUENCE pour les séquences Postgres!

Il est tout à fait contre-intuitif, mais les gens Hibernate complètement foiré sur ce point. Vous devez utiliser GenerationType.AUTO ou Hibernate Démolir vos séquences si vous devez redémarrer / reconstruire votre DB. Il est presque coupable de négligence criminelle qu'ils permettraient ce code d'entrer dans une version de production, mais l'équipe Hibernate est plutôt célèbre pour ses prises de position de tête de taureau vers des positions platement-mal (vérifier leur position sur la gauche JOIN, par exemple).

Tout d'abord, vous devez déterminer quelle version d'Hibernate que vous utilisez. En termes de mise en veille prolongée versions-core, 3.2 et ultérieures introduit un soutien plus cohérent pour les générateurs d'id en particulier 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 ( « hibernate.id.new_generator_mappings ») qui rend les générateurs décrits dans ce blog la façon par défaut sont traitées JPA-annotations. Le réglage est faux par défaut, car Hibernate doit maintenir une compatibilité ascendante avec les anciennes versions. Si vous voulez que le nouveau comportement (ce qui est tout à fait recommandé) puis définissez simplement que la valeur true.

Comment GenerationType est traitée dépend de la version que vous utilisez et si vous avez l'ensemble 'hibernate.id.new_generator_mappings de true. Je considère que vous utilisez 3.6+ (puisque tout est plus, bien, vieux) et n'ont 'set' hibernate.id.new_generator_mappings de true (puisque c'est la recommandation de nouvelles applications):

  1. GenerationType.AUTO -> traités comme GenerationType.SEQUENCE
  2. GenerationType.SEQUENCE -> Cartes à la classe org.Hibernate.ID.Enhanced SequenceStyleGenerator discuté dans le blog
  3. GenerationType.TABLE -> Cartes à la classe org.Hibernate.ID.Enhanced.TableGenerator discuté dans le blog

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 besoin Hibernate REPERCUTEES citations échappées afin de comprendre Postgres et trouver les tables, des colonnes ou des noms de séquences.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top