回答

收藏

我应该让JPA还是数据库级联删除?

技术问答 技术问答 524 人阅读 | 0 人回复 | 2023-09-14

假设我们有两个实体,A和B。B与A具有多对一关系,如下所示:+ ^- P2 I% D( ^) K9 s  a( ^" Y: L
@Entity
! U! d8 ~- b; \: M" upublic class A {7 ?5 }2 E0 `' l3 g/ C
  @OneToMany(mappedBy="a_id")  t1 v3 L4 ^9 {9 j
  private List[B] children;$ H6 a2 ]6 O8 W4 o, \- C: A
}1 x% p6 X# m6 V/ a5 i/ z$ t
@Entity
, @( r7 j& F: r$ ]0 C7 e  \( P4 wpublic class B {2 `# m9 R, }, n6 D' F
  private String data;# n4 l  C5 p1 A& k
}
) U3 C& s  i) s$ A! j( Q现在,我要删除A对象,并将删除操作级联到其所有子项B。有两种方法可以做到这一点:: Y% G; C3 r. [' S/ H
[ol]
: ^$ @1 m8 N4 [3 C添加cascade=CascadeType.ALL, orphanRemoval=true到OneToMany批注中,让JPA删除所有子项,然后再从数据库中删除A对象。, Z2 T/ D) W$ o+ S
1 L/ g* {1 N+ d: H7 G! ]
保持类不变,只需让数据库级联删除操作即可。: S* _$ h, z/ t+ X, ?0 `* m

# q& f# {+ p9 n3 N! c7 X( o% f[/ol]1 p+ ^8 P4 t5 P' I/ Z, ^8 |* Q
使用后面的选项有什么问题吗?这会导致实体管理器保留对已删除对象的引用吗?我之所以选择选项2而不是选项1的原因是,选项1生成了n +. E" A. A1 f' N! X
1条用于删除的SQL查询,当对象A包含许多子项时,这可能花费较长的时间,而选项2仅生成一个SQL查询,然后继续进行操作。快乐地。对此是否有“最佳实践”?
7 k  K3 M7 o& g3 p               
' e$ q3 z, o+ R1 W' o- s: r8 x解决方案:
4 e$ D7 ^' \: ?9 K" X& g! \( @                2 p. p  d3 G( P; x5 ^
* y& S& E: o$ p: e# q

5 M/ K6 a$ B, F( ]* k8 @7 t                如果使用@CascadeOnDelete批注,则在EclipseLink中可以同时使用两者。EclipseLink还将为您生成级联DDL。$ }( [1 I0 [3 _$ F! M
参见: k( ]" E" s# @( D/ h: y
http://wiki.eclipse.org/EclipseLink/Examples/JPA/DeleteCascade
3 Q+ K/ C! k( l- v' H2 e' q3 K7 X这可以通过让数据库进行删除来优化删除操作,还可以通过删除对象来维护缓存和持久性单元。& r* Y* k( u9 K( X& q; b, E, p
请注意,这orphanRemoval=true还将删除从集合中删除的对象,数据库级联约束不会为您提供这些对象,因此仍然有必要在JPA中使用规则。数据库还存在一些无法处理删除的关系,因为数据库只能在约束的相反方向上级联,OneToOne带有外键的a或OneToMany带有联接表的a不能在数据库上级联。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则