Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate JPA-orphaneremovation=true与ON-DELETE-CASCADE-DML子句有何不同_Hibernate_Jpa_Cascade_Cascading Deletes_Orphan Removal - Fatal编程技术网

Hibernate JPA-orphaneremovation=true与ON-DELETE-CASCADE-DML子句有何不同

Hibernate JPA-orphaneremovation=true与ON-DELETE-CASCADE-DML子句有何不同,hibernate,jpa,cascade,cascading-deletes,orphan-removal,Hibernate,Jpa,Cascade,Cascading Deletes,Orphan Removal,我对JPA2.0的属性有点困惑 我想当我使用我的JPA提供者的DB生成工具来创建底层数据库DDL,以便在特定关系上有一个关于删除级联的时,我可以看出这是必要的 但是,如果数据库存在,并且它在关系上已经有了一个关于删除级联的,这还不足以适当地级联删除吗?除此之外,删除还有什么作用 Cheers删除级联上DDL的等效JPA映射为CASCADE=CascadeType。删除。孤立删除意味着当与其“父”实体的关系被破坏时,从属实体将被删除。例如,如果从@OneToMany关系中删除了一个子项,而没有在实

我对JPA2.0的属性有点困惑

我想当我使用我的JPA提供者的DB生成工具来创建底层数据库DDL,以便在特定关系上有一个关于删除级联的
时,我可以看出这是必要的

但是,如果数据库存在,并且它在关系上已经有了一个关于删除级联的
,这还不足以适当地级联删除吗?除此之外,
删除
还有什么作用


Cheers

删除级联上DDL
的等效JPA映射为
CASCADE=CascadeType。删除
。孤立删除意味着当与其“父”实体的关系被破坏时,从属实体将被删除。例如,如果从
@OneToMany
关系中删除了一个子项,而没有在实体管理器中明确删除该子项。

孤立删除
与删除级联上的
无关


孤儿删除
是一件完全ORM特有的事情。当不再从“父”实体引用“子”实体时(例如,从父实体的相应集合中删除子实体时),它将标记要删除的“子”实体


ON DELETE CASCADE
是一个特定于数据库的东西,它在删除“父”行时删除数据库中的“子”行。

从集合中删除子实体的那一刻,也将从数据库中删除该子实体。移除孤儿也意味着你不能改变父母;如果有一个部门有员工,一旦你将该员工调到另一个部门,你就会在刷新/提交时(首先是哪个部门)无意中将该员工从DB中调离。只要你确信父母的孩子在他们的一生中不会迁移到另一个父母,你的士气就是将孤儿移除设置为真。启用“删除”也会自动将删除添加到级联列表中。

示例如下:


删除
员工
实体对象时,删除操作将级联到引用的
地址
实体对象。在这方面,
orphanRemoving=true
cascade=CascadeType.REMOVE
是相同的,如果指定了
orphanRemoving=true
,则
CascadeType.REMOVE
是多余的

这两种设置之间的区别在于对断开关系的响应。例如,当将地址字段设置为
null
或另一个
address
对象时

  • 如果指定了断开连接的
    地址
    实例 将自动删除。这对于清除依赖项非常有用 如果没有来自的引用,则不应存在的对象(例如
    地址
    ) 所有者对象(例如
    员工


  • 如果仅指定了
    cascade=CascadeType.REMOVE
    ,则不执行自动操作 由于断开关系不是移除,因此采取了 手术

为了避免由于孤立删除而挂起引用,应仅为包含私有非共享从属对象的字段启用此功能


我希望这能让事情变得更清楚。

孤立删除与以下场景中的删除级联具有相同的效果:- 假设我们在学生实体和指南实体之间有一个简单的多对一关系,其中许多学生可以映射到同一个指南,并且在数据库中,我们在学生和指南表之间有一个外键关系,这样学生表的id_guide为FK

    @Entity
    @Table(name = "student", catalog = "helloworld")
    public class Student implements java.io.Serializable {
     @Id
     @GeneratedValue(strategy = IDENTITY)
     @Column(name = "id")
     private Integer id;

    @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.REMOVE})
    @JoinColumn(name = "id_guide")
    private Guide guide;
//父实体

    @Entity
    @Table(name = "guide", catalog = "helloworld")
    public class Guide implements java.io.Serializable {

/**
 * 
 */
private static final long serialVersionUID = 9017118664546491038L;

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Integer id;

@Column(name = "name", length = 45)
private String name;

@Column(name = "salary", length = 45)
private String salary;


 @OneToMany(mappedBy = "guide", orphanRemoval=true) 
 private Set<Student> students = new  HashSet<Student>(0);
这里我们用两个不同的student对象映射同一个指南,由于使用了CASCADE.PERSIST,对象图将如下所示保存在数据库表中(在我的例子中是MySql)

学生表:-

ID名称部门ID\U指南 1是的1

2矛盾1

指南表:- ID姓名工资 约翰1500美元

现在如果我想删除其中一个学生,使用

      Student student1 = em.find(Student.class,1);
      em.remove(student1);

当一个学生记录被删除时,相应的指南记录也应该被删除,这就是学生实体中的CASCADE.REMOVE属性进入图片的地方,它的作用是什么;它删除标识符为1的学员以及相应的向导对象(标识符1)。但在本例中,还有一个学生对象映射到同一指南记录,除非我们在指南实体中使用orphanRemoving=true属性,否则上面的删除代码将无法工作。

@GaryK answer绝对不错,我花了一个小时寻找解释,它帮助我理解了

总结:
orphanRemoving=true
的工作原理与
CascadeType相同。只有当我们删除对象(
entityManager.delete(object)
)并且希望同时删除childs对象时,才能删除

在完全不同的位置,当我们获取一些数据时,如
List childs=object.getChilds()
,然后使用
orphandremove=true
删除子对象(
entityManager.remove(childs.get(0)
),将导致该实体对应于
childs.get(0)
将从数据库中删除。

区别在于:
-OrphanRemoving=true:“子”实体在不再被引用时被删除(其父实体可能不会被删除)。
-CascadeType.REMOVE:“子”实体只有在其“父”实体被删除时才会被删除。

实体状态转换 JPA将实体状态转换转换为SQL语句,如INSERT、UPDATE或DELETE

当您
持久化
一个实体时,您正在计划在
实体管理器运行时执行INSERT语句
      Student student1 = em.find(Student.class,1);
      em.remove(student1);
@OneToMany(
    mappedBy = "post", 
    cascade = CascadeType.ALL,
    orphanRemoval = true
)
private List<Comment> comments = new ArrayList<>();
Post post = entityManager.find(Post.class, 1L);
assertEquals(2, post.getComments().size());

entityManager.remove(post);
DELETE FROM post_comment WHERE id = 1
DELETE FROM post_comment WHERE id = 2

DELETE FROM post WHERE id = 1
Post post = entityManager.find(Post.class, 1L);
assertEquals(2, post.getComments().size());

PostComment postComment = post.getComments().get(0);
assertEquals(1L, postComment.getId());

post.getComments().remove(postComment);
DELETE FROM post_comment WHERE id = 1
ALTER TABLE post_comment 
ADD CONSTRAINT fk_post_comment_post_id 
FOREIGN KEY (post_id) REFERENCES post 
ON DELETE CASCADE;
DELETE FROM post WHERE id = 1