JPA级联删除:在NOT NULL列上将子FK设置为​​NULL

时间:2010-04-22 20:25:48

标签: java hibernate jpa

我有两个表: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=?

我不知道从哪里开始寻找问题的根源。

2 个答案:

答案 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属性。