Вызов contactsRepository.save(contact)
с:
@OneToOne(cascade=CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "type")
private ContactType contactType;
вызывает исключение, потому что контекст постоянства каскадирует операцию persist
и видит contactType
как transient
с установленным первичным ключом, готовым к сохранению.Строка с таким же PK уже существует, поэтому возникает ошибка.
Второй случай:
@OneToOne(cascade=CascadeType.MERGE, orphanRemoval = true)
@JoinColumn(name = "type")
private ContactType contactType;
Операция persist
(не merge
), следовательно, не каскадная.Постоянный контекст видит contactType
как transient
и не может идти дальше с persist
, поскольку одна из зависимостей находится в состоянии transient
.
Решение
Избавьтесь от каскада:
@OneToOne
@JoinColumn(name = "type")
private ContactType contactType;
Перед вызовом contactsRepository.save(contact);
убедитесь, что contactType
находится в управляемом состоянии.Вы можете сделать это следующим образом:
contact.setContactType( entityManager.getReference(ContactType.class, contactType.getId()));
Убедитесь, что вы заменили getId()
на получатель первичного ключа.
Слияние contactType
в контекст постоянства с contact.setContactType(contactTypeRepository.merge(contactType));
также допустимо.