Postgresql выдает нулевое значение в столбце «id», нарушает ненулевое ограничение для GenerationType.ИДЕНТИФИКАТОР

#java #spring #postgresql #hibernate #h2

#java #весна #postgresql #спящий режим #h2

Вопрос:

Я пытаюсь автоматически сгенерировать идентификаторы для моей сущности:

 public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
}
 

Моя таблица DB создается с помощью скрипта flyway, а идентификатор столбца задается как ИДЕНТИФИКАТОР

 CREATE TABLE USERS (
   ID INT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
   PRIMARY KEY (ID)
};
 

Затем я пытаюсь сохранить этот объект в своем репозитории:

 @Repository
public interface UserRepository extends JpaRepository<User, Long> {}
 

вот так:

 userRepository.save(user);
 

однако это приводит к ошибке

нулевое значение в столбце «id» нарушает ограничение not-null

Это отображается только при подключении к PostgreSQL: 12.2, если я запускаю тот же код с базой данных h2, он работает нормально.

Почему это сбой в PostgreSQL?

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

1. Работает для меня с гибернацией 5.4

Ответ №1:

вы должны создать последовательность и использовать эту последовательность для идентификатора

     @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_seq")
    @SequenceGenerator(name = "user_id_seq", sequenceName = "user_id_seq")
    private long id;
 

и вы должны создать последовательность в postgresql:

 CREATE SEQUENCE user_id_seq
INCREMENT 5
START 10;
 

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

1. В identity столбце уже есть последовательность, и режим гибернации должен быть достаточно умным, чтобы учитывать GenerationType.IDENTITY аннотацию — это пахнет ошибкой гибернации. Использование правильного identity столбца — правильный (Postgres) способ сделать это.

2. я думаю, что hibernate выполняет поиск в базе данных для правильной последовательности, и когда он не может найти правильную последовательность, это может привести к сбою, но я согласен с вами, что hibernate недостаточно умен

3. Hibernate просто не должен отправлять значение вообще, например, generating insert into users (name) values ('bla') — и это то, что Hibernate (5.4) делает в моем коде

4. какую версию hibernate вы используете?

5. я нахожу это в списке рассылки postgres postgresql.org/message-id /…

Ответ №2:

создать таблицу пользователей

СОЗДАЙТЕ ТАБЛИЦУ USERS (ID serial NOT NULL, ГЕНЕРИРУЕМЫЙ ПО УМОЛЧАНИЮ КАК ИДЕНТИФИКАТОР, ПЕРВИЧНЫЙ КЛЮЧ (ID) };

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

1. Чем это отличается от инструкции CREATE TABLE в вопросе?