MySQL中的@OneToMany错误:无法删除或更新父行:外键约束失败 [英] @OneToMany errors in MySQL: Cannot delete or update a parent row: a foreign key constraint fails

查看:1513
本文介绍了MySQL中的@OneToMany错误:无法删除或更新父行:外键约束失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下一对多关系:

  @Entity 
@Table(name = );
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长ID;
$ b $ @ @OneToMany(fetch = FetchType.EAGER,orphanRemoval = true)
@Cascade(value = {CascadeType.SAVE_UPDATE,CascadeType.DELETE})
@JoinColumn(name = HeaderID)
@Fetch(FetchMode.SELECT)
private Set< ReminderDetails> reminderDetailslist;
}



<$ p
$ b @Table(name =reminderdetails)
public class ReminderDetails implements Serializable {

@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
@Column(name =id,unique = true,nullable = false)
@Basic(fetch = FetchType.EAGER)
私人长ID;

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

当我想删除 ReminderHeader

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

然后我得到以下错误:


无法删除或更新父行:外键约束失败


如何删除 ReminderHeader 及其 ReminderDetails 没有出现此错误的孩子?






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

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

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

我用下面的方法删除

  String query =From ReminderHeader rHdr where rHdr.recipientGUID =:rHeaderGUID; 
查询myQry = getCurrentSession()。createQuery(query);
myQry.setString(rHeaderGUID,RemHeaderGUID);
列表< 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()


I have an one-to-many relationship as follows

@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;
}

and

@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;
}

When I want to delete ReminderHeader from the MySQL database as follows

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

then I get the following error

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

How can I delete ReminderHeader and its ReminderDetails children without getting this error?


Update: I changed the one-to-many relationship as follows:

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

and

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

and I used the following method for deleting

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));
}

but it didn't change anything in the database and no error or exception appears.

解决方案

You have two errors.

First error: you mapped the bidirectional association between header and details twice: once in the header, and once in the details. When you have a bidirectional association, one of the side (the one header side, in this case) must be declared as the inverse of the other side, using the mappedBy attribute:

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

Second error: the DELETE cascade is only applied when you use the Session.delete() method to delete the entity. Delete queries bypass the session entirely (meaning that the entities deleted by the query but previously loaded stay in the session, in the same state as if no query had been executed).

So, to cascade the deletion, you'll have to execute a select query to find all the headers to delete, and then loop over these headers and delete them using session.delete().

这篇关于MySQL中的@OneToMany错误:无法删除或更新父行:外键约束失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆