JPA 2 @SequenceGenerator @GeneratedValue erzeugt eine eindeutige Einschränkungsverletzung

Problemübersicht

Zu scheinbar zufälligen Zeiten erhalten wir die Ausnahme "Postgresql-Duplikatschlüssel verstößt gegen eindeutige Bedingungen." Ich glaube, ich weiß, was unsere Probleme sind, aber ich möchte keine Änderungen am Code vornehmen, ohne einen reproduzierbaren Testfall zu haben. Da wir es in keiner anderen Umgebung als zufällig in der Produktion reproduzieren konnten, bitte ich SO um Unterstützung.

In diesem Projekt haben wir mehrere Postgres-Datenbanken und eine Primärschlüsselsequenz, die für jede Tabelle in jeder Datenbank konfiguriert ist. Diese Sequenzen werden wie folgt erstellt:

create sequence PERSONS_SEQ;
create sequence VISITS_SEQ;
etc...

Wir verwenden diese Sequenzen, um die Primärschlüssel für die Entitäten wie folgt zu generieren:

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

Analyse

Ich denke, ich erkenne 2 Probleme mit dieser Konfiguration:

1) Beide @ Sequenzgeneratoren geben dasselbe Namensattribut an, obwohl sie unterschiedlichen Datenbanksequenzen zugeordnet werden sollen.

2) Das Attribut @SequenceGenerator allocationSize ist standardmäßig auf 50 eingestellt (wir verwenden den Ruhezustand als JPA-Anbieter). Ich denke, die Syntax zum Erstellen von Sequenzen sollte angeben, um wie viel die Sequenz inkrementiert werden soll, insbesondere um 50, um der allocationSize zu entsprechen.

Aufgrund dieser Vermutung sollte der Code folgendermaßen geändert werden:

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

Ich würde dies nur testen, anstatt die Frage zu SO zu stellen, aber wir konnten dieses Produktionsproblem in keiner anderen Umgebung reproduzieren. Und selbst in der Produktion tritt die eindeutige Einschränkungsverletzung nur zu scheinbar zufälligen Zeiten auf.

Fragen:

1) Bin ich in meiner Analyse korrekt, wie die Änderungen lauten sollten, um diese eindeutige Einschränkungsverletzung zu beheben?

2) Was sind die Best Practices für die Verwendung von Sequenzgeneratoren, wenn Sie als JPA-Anbieter den Ruhezustand verwenden?

Antworten auf die Frage(3)

Ihre Antwort auf die Frage