2011-12-25 38 views
3

我有一個一對多的關係如下@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)); 
} 

但它並沒有改變數據庫中的任何內容,也沒有出現錯誤或異常。

回答

5

您有兩個錯誤。

第一個錯誤:您將標頭和細節之間的雙向關聯進行兩次映射:一次在標題中,一次在細節中。當你有一個雙向關聯,側之一(一個報頭一側,在這種情況下)必須被聲明爲另一側的倒數,使用​​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

相關問題