Mar*_*kis 172 hibernate jpa cascade cascading-deletes jpa-2.0
我对JPA 2.0 orphanRemoval属性有点困惑.
当我使用JPA提供程序的数据库生成工具创建底层数据库DDL以获得ON DELETE CASCADE特定关系时,我想我可以看到它是必需的.
但是,如果数据库存在并且它已经存在ON DELETE CASCADE关系,那么这还不足以级联删除吗?什么是orphanRemoval除了做?
干杯
axt*_*avt 260
orphanRemoval与此无关ON DELETE CASCADE.
orphanRemoval是一个完全由ORM特定的东西.它标记"子"实体,当它不再从"父"实体引用时被删除,例如,当您从父实体的相应集合中删除子实体时.
ON DELETE CASCADE是一个特定于数据库的东西,它删除"父"行时删除数据库中的"子"行.
for*_*has 83
这里采用的示例如下:
当一个Employee实体对象被移除,删除操作被级联到引用的Address实体对象.在这方面,orphanRemoval=true并且cascade=CascadeType.REMOVE是相同的,并且如果orphanRemoval=true指定的话,CascadeType.REMOVE则是多余的.
两个设置之间的区别在于断开关系的响应.例如,例如将地址字段设置null为另一个Address对象时.
如果orphanRemoval=true指定,Address则自动删除已断开连接的实例.这对于清除在Address没有所有者对象(例如Employee)的引用时不应存在的依赖对象(例如)是有用的.
如果仅cascade=CascadeType.REMOVE指定,则不会执行自动操作,因为断开关系不是删除操作.
为避免因孤立删除而悬挂引用,仅应为包含私有非共享依赖对象的字段启用此功能.
我希望这更清楚.
Onu*_*nur 45
从集合中删除子实体的那一刻,您也将从数据库中删除该子实体.orphanRemoval也暗示你不能改变父母; 如果有一个拥有员工的部门,一旦你删除该员工将其放入另一个部门,你就会在刷新/提交时无意中从数据库中删除该员工(无论哪个先来).士气是将orphanRemoval设置为true,只要您确定该父级的子女在其存在期间不会迁移到不同的父级.启用orphanRemoval还会自动将REMOVE添加到级联列表中.
Vla*_*cea 25
JPA 将实体状态转换转换为 SQL 语句,如 INSERT、UPDATE 或 DELETE。
当您persist是实体时,您正在安排 INSERT 语句在EntityManager刷新时执行,无论是自动还是手动。
当您remove是一个实体时,您正在调度 DELETE 语句,该语句将在刷新持久性上下文时执行。
为方便起见,JPA 允许您将实体状态转换从父实体传播到子实体。
所以,如果你有父母Post,有一个实体@OneToMany与关联PostComment子实体:
实体中的comments集合Post映射如下:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<Comment> comments = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)
该cascade属性告诉 JPA 提供程序将实体状态转换从父Post实体传递到集合中PostComment包含的所有实体comments。
因此,如果您删除Post实体:
Post post = entityManager.find(Post.class, 1L);
assertEquals(2, post.getComments().size());
entityManager.remove(post);
Run Code Online (Sandbox Code Playgroud)
JPA 提供程序将首先删除PostComment实体,当所有子实体都被删除时,它也会删除该Post实体:
DELETE FROM post_comment WHERE id = 1
DELETE FROM post_comment WHERE id = 2
DELETE FROM post WHERE id = 1
Run Code Online (Sandbox Code Playgroud)
当您将该orphanRemoval属性设置为 时true,JPA 提供程序将在remove从集合中删除子实体时安排操作。
所以,在我们的例子中,
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);
Run Code Online (Sandbox Code Playgroud)
JPA 提供程序将删除关联的post_comment记录,因为集合中PostComment不再引用该实体comments:
DELETE FROM post_comment WHERE id = 1
Run Code Online (Sandbox Code Playgroud)
的ON DELETE CASCADE是在FK级别定义:
ALTER TABLE post_comment
ADD CONSTRAINT fk_post_comment_post_id
FOREIGN KEY (post_id) REFERENCES post
ON DELETE CASCADE;
Run Code Online (Sandbox Code Playgroud)
一旦你这样做,如果你删除post一行:
DELETE FROM post WHERE id = 1
Run Code Online (Sandbox Code Playgroud)
post_comment数据库引擎会自动删除所有关联的实体。但是,如果您错误地删除了根实体,这可能是一个非常危险的操作。
JPAcascade和orphanRemoval选项的优点是您还可以从乐观锁定中受益,以防止丢失更新。
如果使用 JPA 级联机制,则不需要使用 DDL-level ON DELETE CASCADE,如果删除在多个级别上具有许多子实体的根实体,这可能是非常危险的操作。
Her*_*eri 17
DDL的等效JPA映射ON DELETE CASCADE是cascade=CascadeType.REMOVE.孤立删除意味着在与其"父"实体的关系被销毁时删除依赖实体.例如,如果从@OneToMany关系中删除子项而未在实体管理器中明确删除它.
小智 7
区别是:
-orphanRemoval = true:当不再引用“子”实体时,“子”实体将被删除(其父对象可能不会被删除)。
-CascadeType.REMOVE:仅在删除其“父项”时,才删除“子级”实体。
@GaryK答案是绝对伟大,我花了一个小时寻找一个解释orphanRemoval = trueVS CascadeType.REMOVE,它帮助我理解。
总结:仅当我们删除对象 ( ) 并且我们希望子对象也被删除时,它的orphanRemoval = true工作方式相同。CascadeType.REMOVE entityManager.delete(object)
在完全不同的情况下,当我们获取一些数据List<Child> childs = object.getChilds(),然后删除子 ( entityManager.remove(childs.get(0)) 时,orphanRemoval=true会导致对应的实体childs.get(0)从数据库中删除。
| 归档时间: |
|
| 查看次数: |
125863 次 |
| 最近记录: |