Проблема ОбзорJPA 2 @SequenceGenerator @GeneratedValue производит уникальное нарушение ограничения
На первый взгляд случайные моменты времени, мы получаем исключение «PostgreSQL дубликат ключа нарушает ограничение уникальности». Я действительно думаю, что знаю, что такое наша проблема », но я не хочу вносить изменения в код, не имея воспроизводимого тестового примера. Но так как мы не смогли воспроизвести его ни в какой другой среде, кроме случайного производства, я прошу помощи от SO.
В этом проекте имеется несколько баз данных постгрейса и последовательность первичных ключей, настроенная для каждой таблицы в каждой базе данных. Эти последовательности создаются следующим образом:
create sequence PERSONS_SEQ;
create sequence VISITS_SEQ;
etc...
Мы используем эти последовательности для генерации первичных ключей сущностей, как это:
@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;
...
}
Анализ
Я думаю, что распознают 2 проблемы с эта конфигурация:
1) Оба генератора @SequenceGenerator указывают один и тот же атрибут имени, даже если они Предполагается, что они должны отображаться в разных последовательностях базы данных.
2) Атрибут распределения @SequenceGenerator allocSize по умолчанию равен 50 (мы используем hibernate как поставщик JPA), поэтому я думаю, что синтаксис create sequence должен указывать, в какой степени последовательность должна увеличиваться, в частности, на 50, чтобы соответствовать allocSize.
Исходя из этого предположения, я думаю, что код должен быть изменен, чтобы что-то вроде этого:
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;
...
}
я бы просто проверить это, а не задавать вопрос о SO, но опять же, мы не смогли воспроизведите эту проблему производства в любых других средах. И даже в производстве уникальное нарушение ограничений происходит только в кажущиеся случайными временами.
Вопросы:
1) Я правильно в моем анализе того, что изменения должны быть, чтобы исправить это уникальное нарушение ограничения?
2) Каковы наилучшие методы использования генераторов последовательности при использовании hibernate в качестве поставщика JPA?