java - 如果我在更新期间将 json 中的空 id 传递给子实体,为什么 Hibernate 会插入一条新记录
问题描述
我有ff。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 一起更新 COD 。否则,如果我传递了 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 和外键仅作为值。但是在insert语句的最后一行是成功的
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...
它应该只是更新,更新,然后插入。
解决方案
你caseOutlineDetails
用cascade = CascadeType.ALL
. 因此,当您更新 a 时CaseOutlineHeader
,hibernate 会自动更新列表,并在需要时插入行。然后你正在做你的东西并再次插入它。
推荐阅读
- go - Go 上的 API 速率限制
- python - 将二维数组的字符串表示形式从 CSV 列读取到二维 numpy 数组中
- python - mypy:为什么“int”是“float”的子类型?
- ios - 在视图控制器之间推送转换时保持视图
- javascript - 除非发生某些事件,否则如何使所有用户都无法访问 React 中的路由
- javascript - 如何在 WebGL 中创建矢量画笔工具?(如 Clip Studio 或 Concepts)
- angularjs - Angularjs上传多个文件
- snowflake-cloud-data-platform - 来自 s3 的雪花副本,带有 jdbc 但没有加载状态
- github - 如何将插件从 Github 存储库迁移到 Odoo.sh
- excel - 我想搜索每个工作表中的每一行以查找文本,然后返回整行数据