@OneToMany错误:无法删除或更新父行,外键约束失败

问题描述:

我有一个一对多的关系如下@OneToMany错误:无法删除或更新父行,外键约束失败

@Entity 
@Table(name = "reminderheader") 
public class ReminderHeader implements Serializable { 

    @Id 
    @org.hibernate.annotations.GenericGenerator(name = "REMINDER_HEADER_GEN", strategy = "native") 
    @GeneratedValue(generator = "REMINDER_HEADER_GEN") 
    @Column(name = "id", unique = true, nullable = false) 
    @Basic(fetch = FetchType.EAGER) 
    private long id; 

    @OneToMany(fetch = FetchType.EAGER, orphanRemoval = true) 
    @Cascade(value = { CascadeType.SAVE_UPDATE, CascadeType.DELETE }) 
    @JoinColumn(name = "HeaderID") 
    @Fetch(FetchMode.SELECT) 
    private Set<ReminderDetails> reminderDetailslist; 
} 

@Entity 
@Table(name = "reminderdetails") 
public class ReminderDetails implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id", unique = true, nullable = false) 
    @Basic(fetch = FetchType.EAGER) 
    private long id; 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "HeaderID", nullable = false) 
    private ReminderHeader reminderHeader; 
} 

当我想要从MySQL数据库中删除ReminderHeader如下

String query = "delete ReminderHeader rHdr where rHdr.recipientGUID = :rHeaderGUID "; 
Query myQry = getCurrentSession().createQuery(query); 
myQry.setString("rHeaderGUID", RemHeaderGUID); 
int deletedRow = myQry.executeUpdate(); 

然后我得到以下错误

Cannot delete or update a parent row: a foreign key constraint fails

如何删除ReminderHeader及其ReminderDetails儿童没有得到这个错误?


更新:我改变一对多的关系,如下所示:

@OneToMany(fetch = FetchType.EAGER, orphanRemoval = true, mappedBy = "reminderHeader") 
@Cascade(value = { CascadeType.SAVE_UPDATE, CascadeType.DELETE }) 
@Fetch(FetchMode.SELECT) 
private Set<ReminderDetails> reminderDetailslist; 

@ManyToOne(fetch = FetchType.EAGER) 
private ReminderHeader reminderHeader; 

和我用下面的方法用于删除

String query = "From ReminderHeader rHdr where rHdr.recipientGUID = :rHeaderGUID "; 
Query myQry = getCurrentSession().createQuery(query); 
myQry.setString("rHeaderGUID", RemHeaderGUID); 
List<ReminderHeader> remList = myQry.list(); 
for (int i = 0; i < remList.size(); i++) { 
    getCurrentSession().delete(remList.get(i)); 
} 

但它并没有改变数据库中的任何内容,也没有出现错误或异常。

您有两个错误。

第一个错误:您将标头和细节之间的双向关联进行两次映射:一次在标题中,一次在细节中。当你有一个双向关联,侧之一(一个报头一侧,在这种情况下)必须被声明为另一侧的倒数,使用​​mappedBy属性:

@OneToMany(fetch = FetchType.EAGER, orphanRemoval = true, mappedBy = "reminderHeader") 
@Cascade(value = { CascadeType.SAVE_UPDATE, CascadeType.DELETE }) 
@Fetch(FetchMode.SELECT) 
private Set<ReminderDetails> reminderDetailslist; 

第二错误:DELETE级联仅在您使用Session.delete()方法删除实体时才适用。删除查询完全绕过会话(意思是查询删除的实体,但之前加载的实体保留在会话中,处于与没有执行查询相同的状态)。

因此,要级联删除,您必须执行选择查询来查找所有要删除的标题,然后遍历这些标题并使用session.delete()删除它们。

+0

我将两个bean更改为: – 2011-12-25 11:29:11

+0

请检查我的更新 – 2011-12-25 11:35:41

+0

如果您在数据库中没有任何更改,则可能是查询未返回任何内容或发生了回滚。进入调试模式,并检查生成的SQL查询。 – 2011-12-25 12:45:33