使用Hibernate通过公共桥表映射3个实体

时间:2018-10-26 22:42:24

标签: java hibernate

我想模拟一个团队需要多种技能才能运作的事实。 许多人可以具有一定的技能。 一个人有很多技能。 一个人可以成为许多团队的一部分。

我使用Hibernate对这种情况进行建模。 我开始使用团队和技能这两个实体进行构建,并使用@ManyToMany批注来链接这些依赖项。试图添加第三个实体(人)是很困难的。我不知道如何建立该模型,将不胜感激。

我没有太多使用Hibernate的经验,所以这是一个挑战。

我已经搜索了信息,发现的大多数示例都是关于两个连接的实体,而我无法将这些示例扩展到包括第三个实体。

这些是我的实体:

package com.example.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import java.util.Set;

@Entity
public class Team {
    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @ManyToMany
    private Set<Skill> skills;

    @ManyToMany
    private Set<Person> persons;
}



package com.example.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import java.util.Set;

@Entity
public class Skill {
    @Id
    @GeneratedValue
    private Long id;

    private String knowHow;

    @ManyToMany
    private Set<Team> teams;

    @ManyToMany
    private Set<Person> persons;
}



package com.example.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.util.Set;

@Entity
public class Person {
    @Id
    @GeneratedValue
    private Long id;

    private String name;

    private Set<Team> teams;
    private Set<Skill> skills;
}

这些是我的存储库:

package com.example.repository;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.example.entity.Competence;
import com.example.entity.Team;

import java.util.List;

@Repository
public interface TeamRepository extends CrudRepository<Team, Long> {
    List<Competence> findDistinctByKnowHow(String name);
}



package com.example.repository;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.example.entity.Competence;
import com.example.entity.Skill;

import java.util.List;

@Repository
public interface SkillRepository extends CrudRepository<Skill, Long> {

    List<Competence> findDistinctByKnowHow(String knowHow);

}



package com.example.repository;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.example.entity.Competence;
import com.example.entity.Person;

import java.util.List;

@Repository
public interface PersonRepository extends CrudRepository<Person, Long> {

    List<Competence> findDistinctByPerson(String name);

}

3 个答案:

答案 0 :(得分:0)

恐怕您无法做到这一点。该模型包含逻辑上的不一致,并可能导致矛盾。假设您有一个包含两个成员的 TeamA PersonA PersonB )。 PersonA 包含 SkillA ,而 PersonB 包含 SkillB 。这意味着 TeamA 应该包含2个技能( SkillA SkillB )。但是,您的模型应该允许将技能独立于成员放在团队级别。如果只将 SkillA 放在 TeamA skills 属性上,会发生什么情况?

我认为您应该在

之间保持多对多关系
  • 人员技能
  • 团队人员

团队级别的技能属性。

答案 1 :(得分:0)

我认为这个问题值得。

假设三个团队只能看到他们自己添加的能力,那么使用这三个实体之间的公共桥接表可以实现行级安全性。

以一个顾问与VB一起工作的示例为例。她确实不喜欢VB,并且不希望其他团队知道她具有这种技能。

团队A可以知道人员A具有VB技能。 团队B不应该知道人员A具有VB技能。

本来可以将此添加为评论,但我缺乏必要的声誉= /

答案 2 :(得分:0)

解决此问题的一种方法是创建一个仅作为桥接实体存在的实体。这样,您可以在“真实”实体和桥实体之间添加三个不同的一对多关系。这样,您应该能够处理三对多关系。

不过,您可能必须“手动”处理桥实体中的数据。