【问题标题】:JPA - @ManyToMany bidirectional relationship, removing Entity on Inverse Side and error with remaining relationship in JoinTableJPA - @ManyToMany 双向关系,删除反向侧的实体和 JoinTable 中剩余关系的错误
【发布时间】:2016-01-10 16:32:20
【问题描述】:

我在 JPA 中定义了两个实体:Employee 和 Skill。

在这些实体之间定义了关系 @ManyToMany。

public class Employee { 

     @ManyToMany(fetch = FetchType.LAZY)
     @JoinTable(name = "employee_skill",
        joinColumns = @JoinColumn(name = "employee_id"),
        inverseJoinColumns = @JoinColumn(name = "skill_id")
     )
     private Set<Skill> skills = new HashSet<>();
}

public class Skill { 

     @ManyToMany(mappedBy = "skills", fetch = FetchType.LAZY)
     private Set<Employee> skilledEmployees = new HashSet<>(); 
}

现在我有这样的问题: 如果我使用实体管理器删除 Skill 实体。它删除确定。但是在数据库 employee_skill 中的 @JoinTable 中,仍然存在与此已删除实体(其 id)的关联。

我不想在删除 Skill 时删除 Employee,因此所有 CASCADE REMOVING 或 orphanRemoval 在这里都没有用。

我考虑了为什么这种关系不会自动从数据库中删除。当连接表中的这个关联仍然存在时,它会给我 javax.persistence.EntityNotFoundException: Unable to find...

所以我可以在删除技能实体之前手动删除此关联。但这真的是最佳实践吗?

在@ManyToMany 双向关系中删除实体的最佳做法是什么?当删除一个实体(如 Employee 或 Skill)不应该影响另一个实体时?

【问题讨论】:

  • 设置关系的双方是唯一真正的方法......因为您选择了双向关系
  • 你的意思是取消设置?喜欢员工:skill.getEmployees() {employee.remove(skill); } 从数据库中删除技能实体时
  • 确实如此。 “设置”意味着在传递给持久性机制之前(即在刷新、提交之前)使两个集合保持一致。您应该如何处理所有双向关系
  • 是的,我知道,但是因为我不是英语母语,所以我想确保在这种情况下,我需要在此实体上删除双方的关联,以使这种关系正确“设置”:)

标签: java hibernate jpa


【解决方案1】:

由于Employee 是关系的拥有方(基于您的mappedBy 值),因此对其与Skill 对象的关系的任何更新都会更新数据库关联。这是拥有方的责任,它将实现这一点。但反过来是不会发生的。您可能的解决方案之一是手动定义数据库cascade 规则,类似于连接表中的以下内容:

FOREIGN KEY (skill_id) REFERENCES skills (id)
  MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE

这样,对Skills 的任何更新都会更新数据库中的关联。

另一种方法是通过在Employee 中定义一个mappedBy 将拥有方更改为Skill,基于Employee/Skill 的刻板关系,这感觉并不自然。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 2016-09-08
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    相关资源
    最近更新 更多