从休眠集合中删除条目而不获取整个集合

问题描述 投票:0回答:1

使用 Hibernate,我可以在人员/地址之间进行双向关联。个人实体可能有太多地址,我想添加和删除地址集合而不加载整个集合。

下面是描述我的情况的示例,在我的实际情况中,地址实体的数量很大,我想在添加/删除时避免加载所有这些实体。

Java 类:

public class Person
{
   private UUID id;
    @OneToMany(mappedBy = "person", fetch = FetchType.LAZY, cascade= {CascadeType.PERSIST, CascadeType.MERGE})
    private Set<Address> addresses = new HashSet<>();

    public Person addAddress(Address address) {
        addresses.add(address);
        address.setPerson(this);
        return this;
    }

    public Person removeAddress(Address address) {
        // though i want to remove one specific address entity association,
        // it loads all addresses which is a lot impacting perf
        addresses.remove(address);
        address.setPerson(null);
        return this;
    }
}
public class Address {

    @ManyToOne(cascade={CascadeType.PERSIST}, fetch = FetchType.LAZY)
    @NotNull
    private Person person;

    public void setPerson(Person person) {
        this.person = person; ...
    }

}

当我想取消某个地址与 Person 实体的关联时,我调用 person.removeAddress(address) 来加载此人的所有地址。就我而言,有 100 个,我想避免将它们全部加载到内存中。

对实体完成修改后,我会调用

personRepository.flush()
并且不执行任何手动 HQL 查询。

当我只想删除一个给定的地址关联时,是否有任何解决方案可以避免加载此人的所有地址?

database hibernate jpa relational-database hibernate-jpa
1个回答
0
投票
public class Person
{
   private UUID id;
    @OneToMany(mappedBy = "person", fetch = FetchType.LAZY, cascade= {CascadeType.PERSIST, CascadeType.MERGE})
    private Set<Address> addresses = new HashSet<>();

    public Person addAddress(Address address) {
        if (Hibernate.isInitialized(addresses)) {
           addresses.add(address);
        }
        address.setPerson(this);
        return this;
    }

    public Person removeAddress(Address address) {
        if (Hibernate.isInitialized(addresses)) {
           addresses.remove(address);
        }
        address.setPerson(null);
        return this;
    }
}

在上面的添加/删除方法中,我使用

Hibernate.isInitialized
方法来检查集合是否已加载到休眠缓存中,然后才修改集合,否则,我更新关系的另一端,即地址->人员并且有效.

更新关系的另一方就足够了,不需要更新集合,因为地址是此处关系的所有者方。

通过在 Person 类中包含mappedBy属性,我们将其标记为反面。同时,我们还对Address.person字段进行@ManyToOne注解,使Address成为拥有方。

来自:https://www.baeldung.com/hibernate-one-to-many

基于此,Hibernate知道Address的引用更重要,并将Address的引用保存到数据库中。

注意:如果地址收集已初始化,则应使用正确的引用进行更新。否则,可能会导致诸如映射陈旧引用之类的问题。

© www.soinside.com 2019 - 2024. All rights reserved.