#java #spring-boot #jpa
#java #spring-boot #jpa
Вопрос:
У меня есть 3 класса объектов, определенных как показано ниже:
@Entity
public class Rimorchio {
@Id
@GeneratedValue
private long idrimorchio;
@Column(unique = true)
private String targa;
// .... Getters and Setters
}
@Entity
public class Atk {
@Id
@GeneratedValue
private long idatk;
@Column(unique = true)
private String codice;
@Column(unique = true)
private String targa;
@OneToOne
private Rimorchio suggerito;
// .... Getters and Setters
}
@Entity
public class Trasportatore {
@Id
@GeneratedValue
private long idtrasportatore;
@Column(unique = true)
private String nometrasportatore;
@OneToMany(cascade = {CascadeType.PERSIST})
private List<Rimorchio> listarimorchi;
@OneToMany(cascade = {CascadeType.PERSIST})
private List<Atk> listaatk;
@OneToMany(cascade = {CascadeType.PERSIST})
private List<Autista> listaautisti;
// .... Getters and Setters
}
Когда я пытаюсь сохранить в базе данных класс Trasportatore, я получаю следующую ошибку:
org.hibernate.TransientPropertyValueException: object references an unsaved transient instance -
save the transient instance before flushing :
com.petroli.gestionefasipetroli.entities.Atk.suggerito ->
com.petroli.gestionefasipetroli.entities.Rimorchio
Итак, я должен сохранить экземпляр Rimorchio перед экземпляром Atk.
У меня есть структура с репозиторием, который расширяет JpaRepository, и службой, которая просто вызывает
repository.saveAndFlush(trasportatore);
Как я могу определить порядок вставки в БД, чтобы избежать этой проблемы? Или есть другое решение (возможно, избегающее каскадных операций вручную) для достижения этой цели?
Комментарии:
1. Есть ли какая-то причина, по которой у вас нет каскадного сохранения, установленного для отношений OneToOne?
2. Да, потому что Rimorchio в Atk не является обязательным. Если я вставлю туда каскадирование, все будет работать хорошо (я должен удалить каскадирование из Trasportatore). Проблема в том, что может существовать Atk без Rimorchio!
3. Каскадное сохранение не останавливает и не влияет на это — оно не имеет ничего общего с обязательными или необязательными ссылками, только то, что JPA должен делать, если вы вызываете persist, и он находит ссылку на неуправляемый объект. Если у вас есть Atk, которые существуют без экземпляров Rimorchio, для них требуется вызов persist, но для тех, которые уже сохраняются, это недопустимо.
4. Да, но если я добавлю каскадное сохранение в OneToOne, у меня будет исключение SQLIntegrityConstraintViolationException: дублирующая запись. Если я использую каскадное сохранение только в отношении OneToOne, я не могу вставить Rimorchio во вставку Trasportatore.
5. отличаются ли эти экземпляры? Вам нужно исправить вашу модель так, чтобы в X-> Y-> Z-> X’, X== X’. X не будет иметь установленного идентификатора до тех пор, пока не сохранится (или даже после фиксации или сброса), поэтому JPA не может знать, что они представляют одни и те же данные. Если строки ‘targa’ предназначены для уникальной идентификации строки экземпляра, вы можете использовать их в качестве идентификатора, и это может помочь вам справиться с повторным использованием экземпляров, которые должны быть одинаковыми в этом графе объектов.