问题描述
我有以下一对多关系:
@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 $ c
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
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错误:无法删除或更新父行:外键约束失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!