2013-06-11 114 views
8

我有以下休眠的entites:休眠設置外鍵爲空時刪除實體

@Entity 
@Table(name = "model_view") 
public class ModelView { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "modelView_id") 
    private Integer id; 

    @ManyToOne 
    @NotNull 
    @JoinColumn(name = "page_id", nullable = false, insertable = true, updatable = true) 
    private Page page; 

    /* getters and setters */ 
} 

和:

@Entity 
public class Page { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "page_id") 
    private Integer id; 

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    @JoinColumn(name = "page_id") 
    @IndexColumn(name = "modelView_id") 
    private Set<ModelView> modelViews = new HashSet<ModelView>(); 

    /* getters and setters */ 
} 

當我在DAO刪除實體«模型視圖»我有例外:

ORA-01407: unable to replace ("MODEL_VIEW"."PAGE_ID") to NULL 

有什麼不對?爲什麼hibernate在刪除之前將外鍵設置爲NULL?

回答

21

爲什麼hibernate在刪除之前將外鍵設置爲NULL?

Hibernate嘗試通過對FK進行NULL處理來嘗試對您嘗試刪除的記錄進行解引用。不幸的是,在大多數情況下,FK不能爲空。當刪除Page記錄時,必須告訴Hibernate不要更新ModelView實例。

嘗試ModelView改變insertableupdatable上的page@JoinColumn映射錯誤:

@JoinColumn(name = "page_id", nullable = false, insertable = false, updatable = false) 

當使用這些值,ModelView記錄將保留。再說一遍,如果你強制引用完整性,這將不起作用。爲了解決這個問題,你需要打開級聯的刪除。我注意到,在你的代碼中,你已經使用了CascadeType.ALL這應該工作得很好。

這裏是一個SO Q & A,其解釋了這些字段:

In JPA why and how to use insertable and updatable parameter?

我不得不將其固定用false這些值類似的問題。

How can I map "insert='false' update='false'" on a composite-id key-property which is also used in a one-to-many FK?

+0

這不是我的解決方案,因爲在這種情況下,我對插入實體«模型視圖»同樣的錯誤(ORA-01400:無法插入NULL來(「MODEL_VIEW」「PAGE_ID」)。)。我嘗試設置FK爲空,但不是個好主意。還有其他解決方案嗎? – AnEi

+0

這個建議的解決方案_should_也應該用INSERT語句來解決這個問題。當您將'insertable'和'updatable'設置爲'false'時,您告訴Hibernate您將手動保存對'ModelView'記錄的修改。這意味着你需要首先插入/更新'Page'記錄,然後在'ModelView'上設置FK,然後獨立保存這些記錄,最好是所有事務。如果你這樣做,你永遠不應該有一個FK爲NULL的情況。 –

+0

@AnEi如果你仍然有這些錯誤,你能分享一些你使用的代碼嗎? –