2010-04-22 84 views
2

我有两个表:t_promo_program和t_promo_program_param。JPA级联删除:在NOT NULL列上将子FK设置为​​NULL

它们由以下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,休眠打我的数据库有:

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=? 

我在哪里开始寻找丢失为问题的根源。

回答

3

Oh crud,它是PromoProgram中缺少的“mappedBy”字段。

1

仔细检查您是否保持双向关联一致性。那是;请确保链接到PromoProgram作为其父项的所有PromoProgramParam实体也包含在所述父项的params列表中。如果你愿意,不管哪一方“启动”该协会,确保这种情况发生是一个好主意;如果在PromoProgramParam上调用setPromoProgram,让setter自动将自己添加到PromoProgram的params列表中。反之亦然,当在PromoProgram上调用addPromoProgramParam时,让它将自己设置为参数的父项。

我以前也遇到过这个问题,这是因为没有保持双向一致性。我对Hibernate进行了调试,发现它无法将删除操作级联到子级,因为它们不在列表中。但是,它们肯定存在于数据库中,并且导致FK异常,因为Hibernate试图删除父项而没有首先删除其子项(您可能还遇到过@NonNull)。我相信制作PromoProgramParam.promoProgram字段(比如说100次)不可空的正确的“EJB 3.0”就是在@ManyToOne注释中设置optional = false属性。

+0

Upvoted为“optional = false”位。 – 2010-04-22 20:49:29