java - Hibernate 中的孤立删除(当有多个映射对象时)

标签 java hibernate

我有这样的项目结构:

class UserServiceSettingsImpl {
...

    @ManyToOne
    private UserImpl user;

    @ManyToOne
    private ServiceImpl service;
...

}

class ServiceImpl {
....
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "service", orphanRemoval = true)
    private Set<UserServiceSettingsImpl> userServiceSettings;
....

}

class UserImpl {
....
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "user", orphanRemoval = true)
    private Set<UserServiceSettingsImpl> serviceSettings;
....
}

我正在尝试删除 Service 及其所属的所有内容 (UserServiceSettingsImpl),但意外的是,此设置没有被删除(我想是因为它们不是孤儿,因为 UserImpl 也有它们)。所以问题是:有没有一种方法可以删除设置,而不需要手动从用户中删除它们(可能有很多用户有很多设置,迭代它可能需要很多时间)?

最佳答案

如果 UserServiceSettings 也被用户引用,那么在删除服务时,为什么 UserServiceSettings 不会被删除,您是正确的。它们不是孤立的,必须根据您的业务逻辑明确删除。

三个想法:

  1. 使用ORM批量删除实体。
    它与迭代没有太大区别,但可以在仍然使用 ORM 的同时进行优化。 List settingsCopy = new ArrayList<>(service.getSettings()); service.getSettings().clear(); myDao.deleteAll(settingsCopy);

  2. 直接使用HSQL/SQL批量删除。
    这取决于您使用的框架,但通常是这样的,可能在您的存储库/dao 类中:

    delete from UserServiceSettingsImpl o where o.service.id = ?

    但是,hibernate 在删除时不支持 JOIN,据我所知,所以这不起作用。通常需要重新编写 HSQL 以使用“delete where id IN(...)”类型格式。

  3. 设置 CASCADE DELETECASCADE UPDATE位于数据库 DDL 中,位于 ORM 框架之外。 (不推荐。)

但是,如果服务和用户的 UserServiceSettings 有可能通过多个线程同时修改(即使事务边界正确),或者如果这些实体将被修改,那么最后两个选项就会出现问题。删除后在 orm 上下文中使用,无需重新加载。在这种情况下,您可能会在使用最后两种方法时遇到意外和偶发的错误,而应该迭代设置并通过 ORM 进行删除,即使效率很低。

即使使用第一种方法,在删除共享实体时避免高并发环境中的错误也可能很棘手。

关于java - Hibernate 中的孤立删除(当有多个映射对象时),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22561384/

相关文章:

java - 使 JDialog 按钮响应 Enter 键

java - 为什么字节缓冲区在缓冲区未满时给出缓冲区溢出异常

java - 如何使用 Spring Data JPA 获取不同的实体字段?

Java 不会因双逗号而崩溃 "malformed line"

java - 为数据库中的唯一名称创建附加 ID?

java - 多对多 - 选择没有确定字段且结果数量有限的实体集合

hibernate - 如何仅删除前 100 行?

java - 从字符串中检索字符

java - JPA,何时打开和关闭entityManager

hibernate - 为什么Hibernate在启动时要花费数小时的负载?