[英]Hibernate: add existing child entity to new entity with OneToMany bidirectional relationship and persist it ('detached entity passed to persist')
[英]Why Hibernate inserts a new record if i passed an empty id in json to child entity during update
我有事。 pojos:我為簡單起見簡化了它
public class CaseOutlineHeader{
@Id
@GeneratedValue(generator = "COH_SequenceStyleGenerator")
@Column(name = "outline_id")
private Long id;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "outline_id", nullable = true, referencedColumnName = "outline_id",
foreignKey = @ForeignKey(name = "FK_COH_REF_COD_01"))
private List<CaseOutlineDetails> caseOutlineDetails;
}
public class CaseOutlineDetails{
@Id
@GeneratedValue(generator = "COD_SequenceStyleGenerator")
@Column(name = "ID")
private Long id;
@ManyToOne(targetEntity = MaintCaseEvent.class)
@JoinColumn(name = "EVENT_ID", nullable = false,
foreignKey = @ForeignKey(name = "FK_COD_REF_CASE_EVENT"),
referencedColumnName = "CASE_EVENT_ID")
private MaintCaseEvent eventId;
@Column(name = "outline_id")
private Long outlineId;
}
然后是我的服務:如果傳遞的COD json包含不為null的id,這將非常簡單,它將與COD一起更新COH。 否則,如果我傳遞了COD的空ID,我將另存為COD中的新條目。
@Override
@Transactional
public CaseOutlineHeader update(CaseOutlineHeader caseoutline) {
LOG.info("SERVICE: Updating CaseOutlineHeader...{}", caseoutline);
if (!CollectionUtils.isEmpty(caseoutline.getCaseOutlineDetails())) {
caseoutline.getCaseOutlineDetails().forEach(cod -> {
if (cod.getId() != null) {
cod.setUpdatedBy(cod.getUpdatedBy());
cod.setUpdatedDate(new Date());
caseOutlineHeaderRepository.update(caseoutline);
} else {
cod.setOutlineId(caseoutline.getId());
cod.setCreatedBy("dwade");
caseOutlineDetailsRepository.save(cod);
}
});
}
return caseoutline;
}
大張旗鼓地傳遞json數據:
{
"id": 1,
"caseOutlineDetails": [
{
"eventId": { "id": 1 },
"updatedBy": "kobe",
"id" : 1,
"outlineId" : 1
},
{
"eventId": { "id": 2},
"outlineId" : 1
}
],
"caseType": "string",
"code": "updateC",
"description": "updateD",
"updatedBy": "kobe",
"updatedDate": "2018-07-23T00:55:16.767Z"
}
如您所見,我在COD中傳遞了第二個沒有id屬性的數據,它將被保存。 而第一個將更新,其中包含一個ID。
這是我的倉庫:
@Override
public CaseOutlineHeader update(CaseOutlineHeader caseOutlineHeader) {
em.merge(caseOutlineHeader);
em.flush();
return caseOutlineHeader;
}
@Override
public CaseOutlineDetails save(CaseOutlineDetails caseOutlineDetails) {
LOG.info("REPOSITORY : SAVE = " + caseOutlineDetails);
em.persist(caseOutlineDetails);
return caseOutlineDetails;
}
但是在我的記錄器中,我不知道為什么它首先以id和外鍵作為值插入新記錄。 但是在插入語句的最后一行是成功的
Hibernate: insert into case_outline_details (access_level...
Hibernate: update case_outline_header set access_level=?...
Hibernate: update case_outline_details set access_level=?...
Hibernate: select seq_cod.nextval from dual
Hibernate: insert into case_outline_details (access_level...
它應該只是更新,更新然后插入。
您使用cascade = CascadeType.ALL
聲明了caseOutlineDetails
。 因此,當您更新CaseOutlineHeader
,hibernate將自動更新列表,並在需要時插入行。 然后,您正在做您的工作,然后再次插入。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.