我在JPA中定义了两个实体:员工和技能。
此实体之间定义了关系@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<>();
}
现在我有这样的问题:如果我使用实体管理器移除技能实体。它删除了ok。但在数据库employee_skill的@JoinTable中,仍然存在与此已删除实体(其id)的关联。
当我移除技能时,我不想移除Employee,因此所有级联移除或orfanRemove在这里都没有用处。
我想知道为什么这种关系并没有自动从数据库中删除。当联接表中的此关联保留时,它会给我javax.persistence.EntityNotFoundException:找不到
因此,在删除技能实体之前,我可以手动删除这些关联。但这真的是最好的做法吗?
删除@ManyToMany双向关系中的实体的最佳做法是什么?删除Employee或Skill这样的实体时,不应该影响另一个实体吗
由于Employee
是关系的拥有方(基于您的mappedBy
值),对其与Skill
对象关系的任何更新都将更新数据库关联。这是拥有方的责任,它会履行这一职责。但另一种方式是不会发生的。您可能的解决方案之一是手动定义数据库cascade
规则,类似于联接表中的以下内容:
FOREIGN KEY (skill_id) REFERENCES skills (id)
MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE
这样,对Skill
s的任何更新都会更新数据库中的关联。
另一种方法是通过在Employee
中定义mappedBy
来将拥有方更改为Skill
,基于Employee/Skill
的刻板关系,这并不自然。