Problema PanoramicaJPA 2 @SequenceGenerator @GeneratedValue produzione di violazione di vincolo unico
A volte apparentemente casuali otteniamo un'eccezione "chiave duplicata PostgreSQL viola vincolo univoco." Penso di sapere quale sia il nostro problema "s" ma non voglio apportare modifiche al codice senza avere un caso di test riproducibile. Ma dal momento che non siamo stati in grado di riprodurlo in un ambiente diverso da quello casuale nella produzione, sto chiedendo assistenza da SO.
In questo progetto sono presenti più database Postgres e una sequenza di chiavi primaria configurata per ogni tabella in ciascun database. Queste sequenze sono creati in questo modo:
create sequence PERSONS_SEQ;
create sequence VISITS_SEQ;
etc...
Usiamo queste sequenze per generare le chiavi primarie per le entità come questo:
@Entity
@Table(name = "visits")
public class Visit {
@Id
@Column(name = "id")
@SequenceGenerator(name = "seq", sequenceName = "visits_seq")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq")
private int id;
...
}
@Entity
@Table(name = "person")
public class Person {
@Id
@Column(name = "id")
@SequenceGenerator(name = "seq", sequenceName = "persons_seq")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq")
private int id;
...
}
Analisi
Credo di riconoscere 2 problemi con questa configurazione:
1) Entrambi i @SequenceGenerators specificano lo stesso attributo nome anche se sono supposto per mappare a diverse sequenze di database.
2) L'attributo @SequenceGenerator allocationSize è impostato su 50 (stiamo utilizzando l'ibernazione come provider JPA), quindi penso che la sintassi della sequenza di creazione dovrebbe specificare quanto deve aumentare la sequenza, in particolare di 50 per abbinare allocazione.
Sulla base di questa ipotesi, penso che il codice deve essere modificato per qualcosa di simile:
create sequence PERSONS_SEQ increment by 50;
create sequence VISITS_SEQ increment by 50;
etc...
@Entity
@Table(name = "visits")
public class Visit {
@Id
@Column(name = "id")
@SequenceGenerator(name = "visits_seq", sequenceName = "visits_seq")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "visits_seq")
private int id;
...
}
@Entity
@Table(name = "person")
public class Person {
@Id
@Column(name = "id")
@SequenceGenerator(name = "persons_seq", sequenceName = "persons_seq")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "persons_seq")
private int id;
...
}
vorrei solo provare questo piuttosto che porre la domanda su SO, ma ancora una volta, non siamo stati in grado di riprodurre questo problema di produzione in qualsiasi altro ambiente. E anche nella produzione, la violazione del vincolo univoco si verifica solo in momenti apparentemente casuali.
Domande:
1) Ho ragione nella mia analisi di ciò che i cambiamenti dovrebbero essere quello di correggere questa violazione vincolo univoco?
2) Quali sono le migliori pratiche per l'utilizzo di generatori di sequenza quando si utilizza l'ibernazione come provider JPA?