#spring #hibernate #jpa #spring-boot
#spring #спящий режим #jpa #spring-boot
Вопрос:
У меня есть приложение Spring boot, которое уже работает онлайн в течение нескольких месяцев без каких-либо проблем до сегодняшнего дня. У меня есть объект с типом генерации идентификатора sequence:
@Entity
@ComponentScan
public class MyEntity {
/**
*
*/
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
}
С сегодняшнего дня я получаю ошибки при создании и сохранении нового объекта:
Unique index or primary key violation: "PRIMARY_KEY_D92 ON PUBLIC.MyEntity(ID) VALUES (3713, 250)"; SQL statement:
Каждый раз, когда возникает эта ошибка, сгенерированный идентификатор (в данном случае 3713) уже существует в базе данных. Итак, почему вдруг GenerationType.SEQUENCE
генерирует идентификаторы, которые уже существуют?
Редактировать
Я использую базу данных H2 версии 1.4.191
Ответ №1:
Я столкнулся с этой проблемой с гибернацией, но у нас были явные @SequenceGenerator
аннотации. Проблема в том, что SequenceGenerator по умолчанию в JPA имеет allocationSize
значение 50, где последовательность базы данных по умолчанию увеличивается на 1. Эти два значения должны быть одинаковыми. Одним из решений является определение вашего SequenceGenerator и явное задание этого allocationSize.
@SequenceGenerator(name = "my_entity_gen", sequenceName = "my_entity_id_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_entity_gen")
Генераторы должны быть уникальными, если вы не хотите, чтобы две таблицы использовали их совместно.
Другим решением является использование другой стратегии генерации.
@GeneratedValue(strategy = GenerationType.IDENTITY)
Это работает, если база данных уже знает, что запрашивать последовательность при вставке, как они обычно делают, если вы явно не создали последовательность после таблицы.
Первый подход будет запускать два запроса к базе данных для каждой вставки, поэтому он почти наверняка менее эффективен.
Комментарии:
1. Привет. Если я изменю его на
GenerationType.IDENTITY
, я получу только нулевые значения в качестве идентификатора:NULL not allowed for column "ID"
2. Вы пробовали другой подход? Другой способ заставить его использовать последовательность перед каждой вставкой — это установить
hibernate.id.optimizer.pooled.preferred
свойство в вашемpersistence.xml
наnone
. Чувствителен к регистру. Это свойство может быть недоступно до перехода в спящий режим 5. Вы не указали свою версию или базу данных.