【发布时间】:2023-03-13 06:36:01
【问题描述】:
我有 4 个实体:
Profile与companyContract有关系:
@OneToMany(fetch = FetchType.EAGER, mappedBy = "profile", cascade = { CascadeType.ALL })
@Fetch(value = FetchMode.SUBSELECT)
@Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
private List<CompanyContract> companyContracts;
CompanyContract与时间表有关:
@OneToMany(mappedBy = "companyContract", cascade = { CascadeType.ALL },orphanRemoval = true, fetch = FetchType.EAGER)
@Fetch(FetchMode.SUBSELECT)
@Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
private List<Timesheet> timesheets;
@ManyToOne
@JoinColumn(name = "IDPROFILE")
private Profile profile;
时间表与发票有关系:
@OneToMany(mappedBy = "timesheet", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@Fetch(value = FetchMode.SUBSELECT)
@Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
private List<Invoice> invoices;
@ManyToOne
@JoinColumn(name = "IDCONTRACT")
private CompanyContract companyContract;
发票:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ID_TIMESHEET")
private Timesheet timesheet;
所以正如您在此处看到的,我正在使用 org.hibernate.annotations.CascadeType.DELETE_ORPHAN,因此我可以删除父级的子级。
如果我执行这个:
Profile p = companyContract.getProfile();
p.getCompanyContracts().remove(companyContract);
companyContract.setProfile(null);
profileService.update(p);
--->删除顺序应该是:
删除发票 --> 时间表 --> CompanyContract,否?
相反,我收到了这个错误:
org.hibernate.exception.ConstraintViolationException:列“IDCONTRACT”不能为空
我查了一下,这个错误发生在profileService.updateProfile(p);之后
【问题讨论】:
-
您是否尝试在
@JoinColumn上设置nullable=false,在@ManyToOne上设置optional=false?这可能会阻止第一次更新为 null,然后再删除 -
实际上我没有,但你能向我解释一下这些更改将如何阻止你所说的,因为这正是我的问题
-
您需要
@ManyToOne注释吗?通常不需要明确指定目标实体,因为它通常可以从被引用的对象的类型中推断出来。只是一个想法。 -
无论如何,是的,您不能只将
profile设置为null。 -
@JoinColumn和@ManyToOne的那些属性只是限制了更多的映射,并且可能使 hibernate 在生成 sql 查询时做出正确的决定。
标签: java mysql spring hibernate