АВТО_ИНКРЕМЕНТ в базе данных H2 не работает при запросе у почтальона

#spring-boot #postman #h2 #auto-increment

Вопрос:

Я хочу сохранить TODOs в базе данных H2, облегчающей загрузку приложения Spring.

Следующий SQL-скрипт инициализирует базу данных, и она работает правильно:

 DROP TABLE IF EXISTS todos;

CREATE TABLE todos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  title VARCHAR(50) NOT NULL UNIQUE,
  description VARCHAR(250) NOT NULL,
  completion_date DATE,
  priority VARCHAR(6) CHECK(priority IN ('LOW', 'MEDIUM', 'HIGH'))
);

INSERT INTO todos (title, description, priority) VALUES
  ('Create xxx Todo', 'An xxx-TODO must be created.', 'HIGH'),
  ('Delete xxx Todo', 'An xxx-TODO must be deleted.', 'HIGH'),
  ('Update xxx Todo', 'An xxx-TODO must be updated.', 'MEDIUM'),
  ('Complete xxx Todo', 'An xxx-TODO must be completed.', 'LOW');
 

Вывод консоли при запуске Spring Boot:

 Hibernate: drop table if exists todos CASCADE 
Hibernate: drop sequence if exists hibernate_sequence
Hibernate: create sequence hibernate_sequence start with 1 increment by 1
Hibernate: create table todos (id bigint not null, completion_date date, description varchar(250) not null, priority varchar(250) not null, title varchar(50) not null, primary key (id))
Hibernate: alter table todos add constraint UK_c14g1nqfdaaixe1nyw25h3t0n unique (title)
 

Я реализовал контроллер, сервис и перемещение на Java в приложении Spring Boot.
Я использовал Postman для тестирования реализованной функциональности, и получение всех заданий работает хорошо, но создание задания завершается неудачей в первые 4 раза из-за

 org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Unique index or primarky key violated: "PRIMARY KEY ON PUBLIC.TODOS(ID) [1, 'Create xxx Todo', 'An xxx TODO must be created.', NULL, 'HIGH']"
 

Это тело запроса:

 {
    "title": "Creating xxxx Todo via API",
    "description": "An xxxx TODO was created via API.",
    "id": null,
    "completionDate": null,
    "priority": "LOW"
}
 

Это исключение возникает 4 раза со следующим ответом:

 {
    "timestamp": "2021-05-25T17:32:57.129 00:00",
    "status": 500,
    "error": "Internal Server Error",
    "message": "",
    "path": "/api/todo/create"
}
 

С пятой попытки задача создается:

 {
    "title": "Create xxxx Todo via API",
    "description": "An xxxx TODO was created via API.",
    "id": 5,
    "completionDate": null,
    "priority": "LOW"
}
 

и этой записи был присвоен идентификатор 5.
Следовательно, проблема, по-видимому, заключается в количестве вставленных записей во время запуска H2 при запуске Spring Boot и инициализации базы данных H2.

В сущности Todo я аннотировал идентификатор следующим образом:

   @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;
 

Как я могу решить эту проблему, когда я пытаюсь получить доступ к конечной точке создания приложения Spring Boot через postman?

Комментарии:

1. Мы(я) не можем видеть из вашего поста, почему существует уникальное ограничение title , но оно есть ! (спящий режим …добавить ограничение). Но (прямое) решение: Используйте уникальные title s!! (с каждым запросом почтальона)

2. Ты очень целеустремлен. После публикации моего вопроса я уже добавил УНИКАЛЬНОЕ ограничение (я еще отредактировал его в своем вопросе), но исключение все равно возникает. Запрос, который я отправил с помощью Postman, содержит задание с заголовком, которого в настоящее время нет в базе данных.

3. ..хорошо! (sry, заголовок дополнительно запутывает дело) ..но теперь мы(я;) видим: (если сообщение соответствует): С AUTO (на h2), hibernate генерирует hibernate_sequence (с началом=1 и шагом=1), использует это, очевидно … и (конечно же) объясняет первые 4 неисправных идентификатора (которые не учитываются в вашем сценарии инициализации)… решение(ы)…

4. решение(ы): 1. чтобы указать hibernate использовать «правильную стратегию/последовательность автоматического увеличения» 2. просто, но банально: до ALTER hibernate_seqence ..до 5. 3. (если у вас все равно есть сценарий инициализации): Опустите @GeneratedValue (для этого отключите последовательность hiberante)