JPA Hibernate - 在数据库和注释中级联删除 [英] JPA Hibernate - cascade delete in both database and annotation

查看:125
本文介绍了JPA Hibernate - 在数据库和注释中级联删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简介



我很想知道我应该怎么做,因为我已经阅读了许多试图理解这个问题的文章,其中包括许多SO问题。我已经读过的任何内容都与这篇文章相悖。



我想知道在使用级联规则和应用程序定义数据库时会发生什么因为这将决定我是否应采取以下方法或其他方式。



示例表



  create table foo(
id int unsigned not null auto_increment,
primary key(id)
);

create table bar(
id int unsigned not null auto_increment,
foo_id int unsigned not null,
主键(id),
外键( foo_id)在更新级联上引用foo(id)级联



示例类



  @Entity 
@Table(name =foo)
public class Foo {

private int id;
私人列表< Bar>酒吧;

@Id
@GeneratedValue
@Column(name =id)
public int getId(){
return id;
}

@OneToMany(mappedBy =foo,cascade = {CascadeType.ALL})
public List< Bar> getBars(){
返回酒吧;
}

public void setId(){
this.id = id;
}

public void setBars(List< Bar> bars){
this.bars = bars;



$ b @Entity
@Table(name =bar)
public class Bar {

private int id;
private Foo foo;

@Id
@GeneratedValue
@Column(name =id)
public int getId(){
return id;


@ManyToOne
@JoinColumn(name =foo_id,nullable = false)
public getFoo(){
return foo;
}

public void setId(int id){
this.id = id;
}

public void setFoo(Foo foo){
this.foo = foo;
}

}



问题



如果我现在调用一个删除操作(通过 EntityManagerFactory SessionFactory )在 Foo 对象上,会发生以下哪种情况?


  1. hibernate操作将删除 bar 表中的所有记录,其中外键是 Foo 的s foo_id ,然后删除
    Foo 记录。


  2. hibernate操作将删除已加载到会话缓存中的所有相应的 Bar 记录(其中
    可能或可能不全是 bar 记录存在于实际数据库中)和
    ,然后删除 Foo 记录(数据库级联规则将删除任何剩余的 bar 记录)。

  3. hibernate操作将尝试
    删除<首先记录code> Foo ,如果数据库失败然后做
    之前提到的步骤之一。
  4. 还有其他的事情发生在我没有考虑的地方,如果是的话?

  5. li>

考虑到以下这些困境,最好的方法是什么?

Dilemna



如果1为真,那么它会提示:a)仅在数据库中定义级联规则。一定要从应用程序中的对象中删除 bars ,这样它们不会从数据库中脱离(因为数据库将删除它们的记录),然后调用delete <$ c)c> foo 。



OR

应用程序,因为它会彻底地管理数据库的完整性。

不是

c)在这两个中定义级联规则,因为每一个都达到了理想的结果,使得另一个浪费处理。



如果2是真的,那么它会提示:

在数据库和应用程序中定义级联规则,以便Hibernate可以负责管理其实体,并且数据库可以在清除之后清除,因为应用程序不保证删除所有 bar 记录。



如果3是真的,那么它会提示:

在数据库和数据库中定义级联规则因为Hibernate似乎支持已经定义的级联规则d在数据库级别。



如果4是真的,那么它会提示:

这个问题甚至更多

编辑:添加我已阅读的文章...



相关文章



数据库,应用程序或两者的冲突视图:

SO-should-i-let-jpa-or-the-database-cascade-deletions



数据库或应用程序的冲突视图:



SO - 级联 - 删除 - 使用jpa或数据库内更新



本文阐述了JPA提供者实施的内容(尽管应该指出的是,他们使用OpenJPA提供程序进行操作证明):

jpa-tutorial

它指出:


删除和持久操作的级联也适用于尚未加载的那些
实体。它甚至将它们传递给
其他实体,可能遍历整个对象图。


它进入状态:


<刷新,合并和分离的级联仅通过已加载的
实体。


这意味着建议的过程2不成立。

解决方案

如果您在数据库中声明级联,并且休眠数据库将始终先删除(如果它支持它),并且hibernate调用不会真的删除任何内容,但是仍然会运行。但是,由于您使用的是hibernate,因此它的主要优点是可以轻松转换到可能不支持数据库端级联功能的新数据库。因此,即使您的数据库支持级联,并且强调jdbc语句目前没有执行任何操作(它们可能会在未来执行某些操作),您仍然希望将它们留在那里。


Brief

I am wondering what I should do as I have read many articles trying to understand this, including many SO questions. Nothing I have read has quite hit the nail on the head with this one.

I want to know what happens when a database is defined with cascade rules as well as the application since this will define whether I should take the following approach or another.

Example tables

create table foo(
  id int unsigned not null auto_increment,
  primary key(id)
);

create table bar(
  id int unsigned not null auto_increment,
  foo_id int unsigned not null,
  primary key(id),
  foreign key(foo_id) references foo(id) on delete cascade on update cascade
)

Example classes

@Entity
@Table(name = "foo")
public class Foo {

  private int id;
  private List<Bar> bars;

  @Id
  @GeneratedValue
  @Column(name = "id")
  public int getId() {
    return id;
  }

  @OneToMany(mappedBy = "foo", cascade = {CascadeType.ALL})
  public List<Bar> getBars() {
    return bars;
  }

  public void setId() {
    this.id = id;
  }

  public void setBars(List<Bar> bars) {
    this.bars = bars;
  }

}

@Entity
@Table(name = "bar")
public class Bar {

  private int id;
  private Foo foo;

  @Id
  @GeneratedValue
  @Column(name = "id")
  public int getId() {
    return id;
  }

  @ManyToOne
  @JoinColumn(name = "foo_id", nullable = false)
  public getFoo() {
    return foo;
  }

  public void setId(int id) {
    this.id = id;
  }

  public void setFoo(Foo foo) {
    this.foo = foo;
  }

}

Questions

If I now call a delete operation (be it through EntityManagerFactory or SessionFactory) on a Foo object, which of the following will occur?

  1. The hibernate operation will delete all records in the bar table whose foreign key is that of Foo's foo_id and then delete the Foo record.

  2. The hibernate operation will delete all corresponding Bar records that have been loaded into session cache (which may or may not be all bar records that exist in the actual database) and then delete the Foo record (the database cascade rule will then delete any remaining bar records).

  3. The hibernate operation will attempt to delete the Foo record first and if database failure then do one of the aforementioned steps.

  4. Something else happens for which I have not considered, if so what?

Considering the following dilemna assumptions, what is the best approach?

Dilemna

If 1 is true then it would suggest:

A) Define cascade rule in database only. Be sure to remove bars from the object in the application so they are not left detached from the database (as the database will delete their records) then make the call to delete foo.

OR

B) Define cascade rule in application only since it will manage the database integrity thoroughly.

NOT

C) Define cascade rules in both, since each achieve the desired result making the other a waste of processing.

If 2 is true then it would suggest:

Define cascade rules in both database and application so that Hibernate can take care of managing its entities and the database can clean up after since the application is not guaranteed to remove all the bar records.

If 3 is true then it would suggest:

Define cascade rules in both database and application since Hibernate appears to support the cascade rule already being defined at the database level.

If 4 is true then it would suggest:

This question is even more important as I have missed something fundamental!

Edit: Add articles I have read...

Related articles

Conflicting views for database, application or both:

SO - should-i-let-jpa-or-the-database-cascade-deletions

Conflicting views for database or application:

SO - cascading-deletes-updates-using-jpa-or-inside-of-database

This article sheds light on what JPA providers actually do (though it should be noted that they use OpenJPA provider for their proof of operations):

jpa-tutorial

It states that:

The cascading of remove and persist operations applies also on those entities that have not been loaded yet. It even passes through them to other entities, potentially traversing through whole object graph.

It goes on to state:

The cascading of refresh, merge and detach passes only through entities that are already loaded.

This would mean that proposed process 2 is not true.

解决方案

if you declare cascade in the database and hibernate the database will always delete first if it supports it and the hibernate calls will not really delete anything but run anyway. However, since you are using hibernate its main advantage is to allow easy transition to a new database which may not support database side cascade ability. Thus you would want to leave them in there even if your database supports cascade and the hiberate underlining jdbc statements are not currently doing anything (they may do something in the future)

这篇关于JPA Hibernate - 在数据库和注释中级联删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆