所以我有一些实体用作坐标系的基础,为了这篇文章的目的,我们称它们为A
,B
,C
和D
。这些实体中的每一个都有多个@OneToMany
关系,我想级联删除。即删除某些A
时,每个@OneToMany
关系中的所有实体也会被删除。相当标准的东西。
然而,当我想要做的只是级联删除时,我没有看到让这些实体明确跟踪这些关系的重点。每次将新实体添加到@OneToMany
关系时,我都没有看到将所有这些实体(可能是数百万!)加载到内存中的重点(即使用延迟加载仅在加载时加载)访问,但它当然是在添加关系中的新实体时访问的)。
让我们添加一个小例子:
@Entity
public class A {
@Id
private long id;
// ... other fields ...
@OneToMany
private Collection<SomeClass> collection;
}
@Entity
public class SomeClass {
@Id
private long id;
// ... other fields ...
@ManyToOne
A a;
@ManyToOne
B b;
// ... likewise for C, D ...
}
可能有多个类与SomeClass
类似,因此@OneToMany
(和A
)中的多个B,C,D
关系需要添加。这变得乏味乏味。此外,每次添加SomeClass
的新实例时,我都需要加载整个集合,这似乎非常低效(我几乎最终将整个数据库加载到内存中)级联删除!!!)。
如何在不修改底层数据库的情况下实现我想要的目标(例如在定义中指定ON DELETE CASCADE),JPA的设计人员当然考虑过这样的用例吗?也许我在向关系添加实体时需要加载整个集合是不正确的(如果是,请解释原因:))。
此处也提出了类似的问题:JPA: unidirectional many-to-one and cascading delete但它没有一个令人满意的解决方案,也没有讨论整个关系是否被加载到内存中。
答案 0 :(得分:0)
要在不初始化所有实体的情况下实现多级级联,您只能使用DB级联。
别无他法!这就是为什么你找不到满意的解决方案。
至于:
此外,每次添加SomeClass的新实例时,我都需要 加载整个集合,这似乎非常低效(我 几乎最终将我的整个数据库加载到内存中 级联删除!!!)。
您需要了解unidirectional Collections taxonomy:
将一个元素添加到Set中,需要初始化整个集合以强制执行唯一性Set契约。
java.util.Collection或未索引的List意味着你有一个Bag,它在单向用例中非常低效。对于反向集合,它们很好,但这超出了您当前的背景。
您可能正在寻找索引列表(,其中订单在数据库中具体化):
@OrderColumn(name="orders_index")
public List<Order> getOrders() { return orders; }
索引列表将使用索引键进行添加/删除/更新操作。与仅删除所有元素并使用其余元素重新创建集合的Bag相反,索引List将使用索引键仅删除不再属于List的元素。