删除实体时,Hibernate将外键设置为null

AnE*_*nEi 11 hibernate

我有以下hibernate 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 */
}
Run Code Online (Sandbox Code Playgroud)

和:

@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 */
}
Run Code Online (Sandbox Code Playgroud)

当我在DAO中删除实体«ModelView»时,我有异常:

ORA-01407: unable to replace ("MODEL_VIEW"."PAGE_ID") to NULL
Run Code Online (Sandbox Code Playgroud)

怎么了?为什么hibernate在删除之前将外键设置为NULL?

Jes*_*ebb 24

为什么hibernate在删除之前将外键设置为NULL?

Hibernate尝试通过将FK清空来取消引用您尝试删除的记录.不幸的是,在大多数情况下,FK不可归零.你必须告诉Hibernate ModelView在删除Page记录时不要更新实例.

试着改变insertableupdatable虚假的@JoinColumn映射pageModelView:

@JoinColumn(name = "page_id", nullable = false, insertable = false, updatable = false)
Run Code Online (Sandbox Code Playgroud)

使用这些值时,ModelView记录将保留.同样,如果您强制执行参照完整性,这将不起作用.要解决这个问题,您需要打开删除级联.我注意到你的代码已经在使用CascadeType.ALL哪个应该可以正常工作.

这是一个SO Q&A,它解释了这些领域:

在JPA中为什么以及如何使用可插入和可更新的参数?

我有一个类似的问题,通过使用false这些值来解决.

如何在复合id键属性上映射"insert ='false'update ='false'",该属性也用于一对多FK?

  • @MaksimGumerov 你不应该在`ModelView.page` 上设置`updatable = false`,你应该在`Page.modelViews` 上设置它。仍然可以通过在代码中设置 ModelView.page 来更新数据库中的 ModelView.page_id 字段,只是无法使用代码中的 Page.modelViews 更新 FK。如果您仍然感到困惑,请提出一个新问题,这样您将获得更多帮助。随意链接到这里的新问题,我会看看。 (2认同)