【问题标题】:JPA 2/Hibernate - Best way to update complex entities?JPA 2/Hibernate - 更新复杂实体的最佳方式?
【发布时间】:2011-02-19 23:37:33
【问题描述】:

我是 JPA/Hibernate 的新手,我想知道,更新复杂实体的最佳方式通常是什么?

例如,考虑下面的实体:

@Entity
public class Employee {

    @Id
    private long id;
    @Column
    private String name;
    @ManyToMany
    private List<Positions> positions;

    // Getters and setters...

}

更新职位引用的最佳方式是什么?目前,一项服务正在向我传递员工应该拥有的职位列表。创建它们很容易:

for (long positionId : positionIdList) {
    Position position = entityManager.find(positionId);
    employee.getPositions.add(position);
}

entityManager.persist(employee);

但是,在更新员工时,我不确定更新员工职位的最佳方式是什么。我认为有两种选择:

  1. 我解析位置 id 的列表并确定是否需要添加/删除该位置(这似乎不是一个有趣的过程,并且可能会导致许多删除查询)

  2. 我删除所有位置,然后重新添加指定位置。 JPA/Hibernate 中是否有一种方法可以使用一个 sql 命令删除所有子项(在本例中为位置)?

我是不是想错了?大家有什么推荐的?

【问题讨论】:

    标签: java hibernate jpa jakarta-ee jpa-2.0


    【解决方案1】:

    怎么样

    employee.getPositions.clear(); // delete all existing one
      // add all of them again
     for (long positionId : positionIdList) {
        Position position = entityManager.find(positionId);
        employee.getPositions.add(position);
    }
    

    虽然它可能不是最有效的方法。有关详细讨论,请参阅here。 级联在这里没有多大帮助,因为在多对多关系中,职位可能不会被孤立,因为它们可能附加到其他员工,甚至根本不应该被删除,因为它们可以独立存在。

    【讨论】:

    • 那么persist() 将负责删除列表中不再存在的实体,并添加新实体?
    • 试一试;)。请注意,您需要添加@JoinTable 注解来定义关系表和对应的列才能使其工作,请参见示例en.wikibooks.org/wiki/Java_Persistence/ManyToMany
    【解决方案2】:

    JPA/Hibernate 对此有支持。这叫做级联。通过使用@ManyToMany(cascade=CascadeType.ALL)(或将级联类型限制为PERSISTMERGE),您可以指定当拥有对象存在时,该集合应该被持久化(合并/删除/等)。

    当涉及到删除时,有一种特殊情况,即对象成为数据库中的“孤儿”。这是通过设置orphanRemoval=true

    来处理的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-10
      • 2019-11-05
      • 2012-01-08
      • 2011-06-04
      • 2015-05-10
      • 2018-07-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多