Domanda

Ho configurato per utilizzare Hibernate sequenza di PostgreSQL (tramite annotazioni) per generare valori per chiave primaria id colonna come segue:

@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;
}

Quello che vedo con questa configurazione è che Hibernate è già assegnando lo id valori> 3000 sul persistere, mentre la query sul usati spettacoli sequenza il seguente:

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

(1 row)

Domande:
C'è sbagliato qualcosa o no?
Dovrebbe hibernate sincronia con la tabella di sequenza?
In caso contrario, dove va a memorizzare l'ultimo ID generato?

Grazie.

È stato utile?

Soluzione

Ho avuto lo stesso problema. Esso è legato alla id assegnazione strategie di Hibernate. Whe n si sceglie GenerationType.SEQUENCE , Hibernate usa strategia HiLo che assegna gli ID a blocchi di 50 per impostazione predefinita. Così si può impostare in modo esplicito allocationSize valore in questo modo:

@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;
}

Anche se, ho anche sentito opinioni che usare la strategia HiLo con allocationSize = 1 non è una pratica buona. Qualcuno raccomanda di usare GenerationType.AUTO , invece quando si ha a che fare con le sequenze di database gestiti

Aggiornamento: è finito per andare con allocationSize = 1, e le cose sembrano funzionare come mi aspetto ora. La mia domanda è tale che non ho davvero bisogno di blocchi di ID in ogni caso, in modo da YMMV .

Altri suggerimenti

Non utilizzare GenerationType.SEQUENCE per le sequenze di Postgres!

E 'completamente contro-intuitivo, ma la gente Hibernate completamente incasinato su questo. È necessario utilizzare GenerationType.AUTO o Hibernate demolire i tuoi sequenze se si deve riavviare / ricostruire il DB. E 'quasi criminalmente negligente che permetterebbero questo codice per entrare in una build di produzione, ma la squadra di Hibernate è piuttosto famosa per le loro posizioni dalla testa di toro verso posizioni categoricamente-sbagliate (check out la loro posizione a sinistra join, per esempio).

In primo luogo, è necessario determinare quale versione di Hibernate che si sta utilizzando. In termini di versioni sospensione-core, 3.2 in poi introdotto un sostegno più consistente per generatori id soprattutto in riferimento a definito annotazioni. Vedere http://in.relation.to/Bloggers/New323HibernateIdentifierGenerators per una discussione.

Avanti 3.6 ha introdotto una regolazione ( 'hibernate.id.new_generator_mappings'), che rende i generatori discussi in questo blog il modo di default JPA-annotazioni vengono gestiti. L'impostazione è falso per default, perché Hibernate deve mantenere la compatibilità all'indietro con le versioni precedenti. Se si desidera che il nuovo comportamento (che è completamente consigliato) quindi è sufficiente impostare che l'impostazione su true.

Come GenerationType viene gestito dipende dalla versione che si sta utilizzando e se è stato impostato 'hibernate.id.new_generator_mappings' true. I assumerà che si sta utilizzando 3.6 e versioni successive (dal momento che nulla più vecchio è, beh, vecchio) e non avere impostato 'hibernate.id.new_generator_mappings' a true (dal momento che è la raccomandazione per nuove applicazioni):

  1. GenerationType.AUTO -> trattato come GenerationType.SEQUENCE
  2. GenerationType.SEQUENCE -> Mappe alla classe org.hibernate.id.enhanced.SequenceStyleGenerator discusso nel blog
  3. GenerationType.TABLE -> Mappe alla classe org.hibernate.id.enhanced.TableGenerator discusso nel blog

In Postgres farei questo:

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

Per lo più con i nomi maiuscoli Hibernate necessità di essere passato citazioni sfuggiti al fine di comprendere Postgres e trovare le tabelle, colonne o nomi di sequenze.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top