单向关系的JPA级联,无需加载所有内容

时间:2014-07-24 00:05:36

标签: java hibernate jpa

所以我有一些实体用作坐标系的基础,为了这篇文章的目的,我们称它们为ABCD。这些实体中的每一个都有多个@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但它没有一个令人满意的解决方案,也没有讨论整个关系是否被加载到内存中。

1 个答案:

答案 0 :(得分:0)

要在不初始化所有实体的情况下实现多级级联,您只能使用DB级联。

别无他法!这就是为什么你找不到满意的解决方案。

至于:

  

此外,每次添加SomeClass的新实例时,我都需要   加载整个集合,这似乎非常低效(我   几乎最终将我的整个数据库加载到内存中   级联删除!!!)。

您需要了解unidirectional Collections taxonomy

  1. 将一个元素添加到Set中,需要初始化整个集合以强制执行唯一性Set契约。

  2. java.util.Collection或未索引的List意味着你有一个Bag,它在单向用例中非常低效。对于反向集合,它们很好,但这超出了您当前的背景。

  3. 您可能正在寻找索引列表(,其中订单在数据库中具体化):

    @OrderColumn(name="orders_index")
    public List<Order> getOrders() { return orders; }
    
  4. 索引列表将使用索引键进行添加/删除/更新操作。与仅删除所有元素并使用其余元素重新创建集合的Bag相反,索引List将使用索引键仅删除不再属于List的元素。