У меня есть два столбца в двух отдельных объектах

Организация интервью

@OneToOne(cascade=CascadeType.PERSIST, orphanRemoval = true)
@JoinColumn(name = "applicant_id", nullable=false)
private Applicant applicant_id;

Заявитель

@OneToOne(mappedBy="applicant_id", cascade = CascadeType.ALL, orphanRemoval = true)
private Interview interview_id;

Вопрос в том, как мне правильно сопоставить это, чтобы я мог запускать service.deleteInterview(); и удалять только запись объекта interview?

Если я использую cascadeType.all, который удаляет объект applicant. Я попытался изменить это, чтобы сохранить, тогда я получаю ошибку 500, говорящую, что объект будет воссоздан, если функция будет вызвана.

Добавление orphan removal=true закончилось этим исключением org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null];

Я думал о назначении mappedBy сущности interview, однако я не уверен, что это может быть решением, а также у меня есть оговорки, так как моя сущность interview создается после создания applicant сущность.

1
Kyan 3 Дек 2018 в 23:54

1 ответ

Лучший ответ

Вы должны использовать только cascade = ... и orphanRemoval = ... для родительского объекта (в вашем случае Applicant). Использование каскадов с обеих сторон ассоциаций не имеет смысла (для любых отношений, а не только один-к-одному). Подумайте, что делает каскадирование и что происходит, когда вы пытаетесь создать новый Interview. CascadeType.PERSIST говорит, что объекту Interview необходимо создать Applicant, если объекту интервью было задано поле кандидата. Как только кандидат создан, он видит, что у него есть CascadeType.ALL, что означает, что ему необходимо сохранить любое поле Interview, которое у него есть, поэтому он снова попытается создать Interview, что не имеет смысла, поскольку вы уже создали интервью.

Я предполагаю, почему он удаляет Applicant, потому что у вас есть orphanRemoval с обеих сторон. Hibernate смотрит на Interview и думает, что, поскольку у него есть orphanRemoval, он является родительской стороной ассоциации, поэтому после удаления Interview он думает, что Applicant больше не нужен, и поэтому удаляет и эту запись.

В документах Hibernate указано, что здесь:

... Только родительская сторона ассоциации имеет смысл каскадировать переходы от состояния объекта к дочерним.

Просмотрите некоторые примеры в этом руководстве, чтобы увидеть, как они используют каскадирование в отношениях OneToOne.

2
dyslexit 3 Дек 2018 в 21:53