【问题标题】:How to properly delete a row referenced in as a forigen key in JPA (Java, Spring, Hibernate and Postgres)如何在 JPA(Java、Spring、Hibernate 和 Postgres)中正确删除作为外键引用的行
【发布时间】:2020-11-28 04:09:54
【问题描述】:

这个问题应该很常见,但我找不到任何相关信息。有一个 Spring 应用程序,其中我们有 departmentsemployees 表(在 Postgres 上,如果这很重要),每个员工都有一个非空的 department_id(FK 到 departments,没有任何 on delete)和每个部门有一个可以为空的manager_id(FK 到employees,没有任何on delete)。现在我正在尝试删除她自己部门的经理的员工。所以我要做的是(JPA):

@Entity
public class Department {
  @Id Integer id;
  @Column Integer managerId;
}

@Entity
public class Employee {
  @Id Integer id;
  @Column @NotNull Integer departmentId;
}

@Transactional
public void deleteEmployee(Integer employeeId) {
  val employee = employeeRepository.getById(employeeId);
  val department = departmentRepository.getById(employee.getDepartmentId());
  if (employeeId.equals(department.getManagerId())) {
    department.setManagerId(null);
    departmentRepository.save(department);
  }
  employeeRepository.delete(employee);
}

但交易失败并抱怨在departments 中引用了员工这一事实。 (如果我在新事务中取消设置 manager_id 列,则操作成功,显然)。当我检查调试日志时,我看到 Hibernate 首先执行“删除员工”查询。如何强制 JPA/Hibernate 以正确的顺序运行查询?或者这样做的正确方法是什么?谢谢。

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    这还不够吗?

    @Transactional
    public void deleteEmployee(Integer employeeId) {
        val employee = employeeRepository.getById(employeeId);
        employeeRepository.delete(employee);
    }
    

    【讨论】:

    • 需要取消设置manager ID,否则FK约束无法删除记录。
    • 对不起,我错过了经理的部分。您正在使用 SpringData,对吗?也许更好地代表与 JPA 的关系会开始有所帮助。否则,您应该将部门经理设置为空(如果这确实有意义),合并(保存在 SpringData 中?)部门然后刷新并最终删除员工
    猜你喜欢
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-22
    • 2018-12-16
    • 2019-11-13
    • 2020-04-17
    相关资源
    最近更新 更多