2013-06-11 78 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如果你仍然有这些错误,你能分享一些你使用的代码吗? –