【问题标题】:Mapping 3 entities through a common bridge table using Hibernate使用 Hibernate 通过一个公共桥表映射 3 个实体
【发布时间】:2018-10-31 00:09:58
【问题描述】:

我想模拟一个团队需要多种技能才能发挥作用的事实。 很多人都可以有一定的技能。 一个人有很多技能。 一个人可以加入多个团队。

我使用 Hibernate 来模拟这个场景。 我开始构建两个实体,团队和技能,并使用 @ManyToMany 注释来链接这些依赖项。尝试添加第三个实体 person 是困难的地方。我不明白我应该如何构建这个模型,非常感谢任何帮助。

我没有太多使用 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);

}

【问题讨论】:

    标签: java hibernate


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      我认为你应该留下多对多的关系

      • 技能
      • 团队人员

      团队级别的skills属性应该派生出来。

      【讨论】:

        【解决方案3】:

        我认为这个问题有可取之处。

        在三个实体之间使用公共桥接表允许通过设计实现行级安全性,假设团队只能看到他们自己添加的能力。

        以顾问在一个团队中使用 VB 为例。她真的不喜欢 VB,不想让她的其他团队知道她有这个技能。

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

        我会将此添加为评论,但我缺乏必要的声誉 =/

        【讨论】:

          猜你喜欢
          • 2017-03-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-15
          • 2011-10-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多