null

Не сохраняется объект в базу. В чем может быть проблема?

В этой статье разберем проблемы, которые приводят к тому, что Hibernate не сохраняет объект в базу с ошибкой could not execute statement; SQL [n/a]; constraint [“id" of relation "ProblemClass”];: частые проблемы и пути их решения. 

Другими словами: “У меня не сохраняется объект в базу. Как мне это исправить?”

Эта ошибка сигнализирует о нарушении ограничения (constraint violation) при попытке сохранить объект в базу данных, а именно проблемы с генерацией id.
 

Вариант 1. Проверьте настройку генерации

 

В сущностях Hibernate используется аннотация @GeneratedValue для генерации идентификатора записи в таблице, а в самой таблице поле id должно быть автоинкрементируемое.
 

Возможное решение:

 

1. Для того, чтобы узнать, явзяется ли поле автоинкрементируемым можно воспользоваться следующей командой:

SELECT column_name, column_default FROM information_schema.columns WHERE table_name = 'target_date' AND column_name = 'id';


1.1 В PostgreSQL, например, автоинкрементное поле можно создать при помощи использования типа данных bigserial

create table problem_class (
    id bigserial primary key,
    ...
);

1.2. Если таблица уже существует, можно добавить автоинкремент с помощью команды:

alter table problem_class alter column id set default nextval('problem_class_id_seq');

2. Добавьте аннотацию @GeneratedValue для поля id
 

@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
open var id: Long? = null

Вариант 2. Проверьте, что значения id не выставляются вручную

Ошибка также может возникнуть, если вы случайно задаёте значение id вручную перед сохранением объекта, что приводит к конфликту с автоинкрементным значением.


Возможное решение:


При создании нового объекта убедитесь, что значение id остаётся null. В таком случае значение id будет сгенерировано автоматически при сохранении записи.
 

Вариант 3. Проверьте, что у связных объектов присутствует двусторонняя связь и каскадирование

Когда вы сохраняете объект ParentClass, связанные с ним объекты ProblemClass не сохраняются автоматически, если не включено каскадирование операций. Вам нужно явно указать, что при сохранении ParentClass должны сохраняться и связанные объекты ProblemClass. И убедитесь в существовании связи с обратной стороны

 

Возможное решение:
Чтобы это сделать, добавьте свойство cascade = [CascadeType.ALL] в аннотацию @OneToMany для поля problemClass в объекте ParentClass

@OneToMany(fetch = FetchType.EAGER, mappedBy = "parentClass", cascade = [CascadeType.ALL]) 
open var problemClass: MutableSet<ProblemClass> = mutableSetOf()

С обратной стороны эта связь должна выглядеть следующим образом:

@ManyToOne @JoinColumn(name = "parent_class_id") 
open var parentClass: ParentClass