简体   繁体   English

JPA - @ManyToMany 双向关系,删除反向侧的实体和 JoinTable 中剩余关系的错误

[英]JPA - @ManyToMany bidirectional relationship, removing Entity on Inverse Side and error with remaining relationship in JoinTable

I have two entities defined in JPA: Employee and Skill .我在 JPA 中定义了两个实体: EmployeeSkill

Between this entities is defined relationship @ManyToMany .在这个实体之间定义了关系@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<>(); 
}

Now I have such problem: If I remove Skill entity using entity manager.现在我有这样的问题:如果我使用实体管理器删除技能实体。 It removes ok.它删除确定。 But in @JoinTable in database employee_skill there remains associations with this removed entity (its id).但是在数据库employee_skill@JoinTable中,仍然存在与这个被移除的实体(它的id)的关联。

I do not want to remove Employee when I am removing Skill so all CASCADE REMOVING or orphanRemoval are not useful here.我不想在删除Skill时删除Employee ,所以所有 CASCADE REMOVING 或 orphanRemoval 在这里都没有用。

I consider why this relationship isn't automagically removed from database.我考虑为什么这种关系不会自动从数据库中删除。 When this association in join table remains it gives me javax.persistence.EntityNotFoundException: Unable to find...当连接表中的这个关联仍然存在时,它会给我javax.persistence.EntityNotFoundException: Unable to find...

So I could remove this associations manually, before removing Skill entity.所以我可以在删除 Skill 实体之前手动删除这个关联。 But is it really the best practice?但这真的是最佳实践吗?

What will be the best practice to remove entities in @ManyToMany bidirectional relationships?删除@ManyToMany 双向关系中的实体的最佳做法是什么? When removing one entity like Employee or Skill shouldn't effect the other entity?删除一个实体(如 Employee 或 Skill)不应该影响另一个实体?

Since Employee is the owning side (based on your mappedBy value) of the relationship, any update on its relationship with Skill objects would update the database associations. 因为Employee拥有方 (根据您mappedBy关系的价值),它与关系的任何更新Skill对象将更新数据库关联。 That's the responsibility of the owning side and it would fulfill that. 那是拥有一方的责任,它将实现这一目标。 But the other way around is not gonna happen. 但是反之亦然。 One of your possible solutions is to define database cascade rules manually, something like following in the join table: 您可能的解决方案之一是手动定义数据库cascade规则,类似于联接表中的以下操作:

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

This way, any update to Skill s would update the associations in database. 这样,对Skill的任何更新都会更新数据库中的关联。

The other approach is to change the owning side to Skill by defining a mappedBy in Employee , which does not feel that natural based on Employee/Skill stereotypical relationships. 另一种方法是通过在Employee定义一个mappedBy来将拥有方更改为Skill ,这基于Employee/Skill刻板印象关系并不自然。

6 años despues traigo tu respuesta. 6 años despues traigo tu respuesta。 Si utilizasel mappedBy y borras desde Skill te dara problemas de contraints. Si utilizasel mappedBy y borras desde Skill te dara problemas de contraints。 Utiliza lo siguiente:使用方法:

public class Employee { 

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

public class Skill { 

     @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
     @JoinTable(name = "employee_skill",
        joinColumns = @JoinColumn(name = "skill_id"),
        inverseJoinColumns = @JoinColumn(name = "employee_id")
     )
     private Set<Employee> skilledEmployees = new HashSet<>(); 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM