我有两个表:t_promo_program和t_promo_program_param。
它们由以下JPA实体代表:
@Entity
@Table(name = "t_promo_program")
public class PromoProgram {
@Id
@Column(name = "promo_program_id")
private Long id;
@OneToMany(cascade = {CascadeType.REMOVE})
@JoinColumn(name = "promo_program_id")
private List<PromoProgramParam> params;
}
@Entity
@Table(name = "t_promo_program_param")
public class PromoProgramParam {
@Id
@Column(name = "promo_program_param_id")
private Long id;
//@NotNull // This is a Hibernate annotation so that my test db gets created with the NOT NULL attribute, I'm not married to this annotation.
@ManyToOne
@JoinColumn(name = "PROMO_PROGRAM_ID", referencedColumnName = "promo_program_id")
private PromoProgram promoProgram;
}
当我删除PromoProgram时,Hibernate会使用以下命令点击我的数据库:
update
T_PROMO_PROGRAM_PARAM
set
promo_program_id=null
where
promo_program_id=?
delete
from
t_promo_program
where
promo_program_id=?
and last_change=?
我不知道从哪里开始寻找问题的根源。
答案 0 :(得分:3)
哦,这是PromoProgram中缺少的“mappedBy”字段。
答案 1 :(得分:1)
仔细检查您是否保持双向关联一致性。那是;确保链接到PromoProgramParam
作为其父级的所有PromoProgram
实体也包含在所述父级params
列表中。如果你愿意,不管哪一方“发起”这种关联,确保这种情况发生是个好主意;如果在PromoProgramParam上调用setPromoProgram,请让setter自动将其自身添加到PromoProgram的params
列表中。反之亦然,当在PromoProgram上调用addPromoProgramParam时,让它自己设置为param的父级。
我之前也遇到过这个问题,这是因为没有保持双向一致性。我调试了Hibernate,发现它无法将删除操作级联到子节点,因为它们不在列表中。但是,它们肯定存在于数据库中,并导致FK异常,因为Hibernate试图仅删除父节点而不先删除其子节点(您可能也会遇到@NonNull)。
仅供参考,我认为正确的“EJB 3.0” - 使PromoProgramParam.promoProgram字段(比如100次)不可为空是在@ManyToOne注释上设置optional = false属性。