小编典典

使用@ ElementCollection,@ MapKeyJoinColumn做多对多关系时参考关键问题

java

我正在尝试多对多关系,团队成员可以从事多个项目,一个项目可以有多个团队成员,表结构如下,

create table TBL_PROJECT_ONE(
       id integer primary key generated always as identity(start with 12,increment by 3),
       name varchar(50)
)

create table TBL_TEAM_MEMBER_ONE(
    id integer primary key generated always as identity(start with 7,increment by 5),
    name varchar(50),
    salary integer
)

create table EMP_PRJ_CADRE(
    MEMBER_ID integer references TBL_TEAM_MEMBER_ONE,
    PRJ_ID integer references TBL_PROJECT_ONE,
    CADRE varchar(10),
    constraint PK_001_EMP_TEAM primary key (MEMBER_ID,PRJ_ID)
)

在这里,我创建了一个新表来存储关系,现在请遵循Employee实体,

@Entity
@Table(name="TBL_TEAM_MEMBER_ONE")
public class EmployeeEntityFour implements Serializable{
   public EmployeeEntityFour(){}
   public EmployeeEntityFour(String empName,Integer salary){
   ...
   ..
   }
   @Id
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="ID")
   private Integer empId;

   @Column(name="NAME")
   private String empName;

   @Column(name="SALARY")
   private Integer empSal;

   @ElementCollection(fetch= FetchType.LAZY)
   @CollectionTable(name="EMP_PRJ_CADRE")
   @MapKeyJoinColumn(name="PRJ_ID")
   @Column(name="CADRE")
   private Map<ProjectEntityOne,String> employeeCadre;
   ...
   ..
   .
}

请遵循项目实体的映射,

@Entity
@Table(name="TBL_PROJECT_ONE")
public class ProjectEntityOne implements Serializable{
   public ProjectEntityOne(){}
   public ProjectEntityOne(String name){
     this.projectName = name;
   }

   @Id
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="ID")
   private Integer projectId;

   @Column(name="NAME")
   private String projectName;

   @ElementCollection(fetch= FetchType.LAZY)
   @CollectionTable(name="EMP_PRJ_CADRE")
   @MapKeyJoinColumn(name="MEMBER_ID")
   @Column(name="CADRE")
   private Map<EmployeeEntityFour,String> employeeCadre;
   ....
   ..
   .
}

在主要方法测试中,编写的代码如下,

ProjectEntityOne proj = new ProjectEntityOne("Citi Grand Central");        
Map<EmployeeEntityFour,String> cadreMap = new HashMap<EmployeeEntityFour,String>();
cadreMap.put(new EmployeeEntityFour("Murlinarayan Muthu",34000), "Senior Software Engineer");
cadreMap.put(new EmployeeEntityFour("Gopalkrishna Rajnathan",64000), "Software Engineer");
cadreMap.put(new EmployeeEntityFour("Premanna Swaminathan",94000), "Project Manager");

proj.setEmployeeCadre(cadreMap);

em.persist(proj);

但我得到一个错误是

ERROR: 'PROJECTENTITYONE_ID' is not a column in table or VTI 'APP.EMP_PRJ_CADRE'.

当在两个实体中我都指定了@MapKeyJoinColumn时,由于第三张表的列不正确,我也收到了一个错误。

我想念的地方


阅读 210

收藏
2020-11-30

共1个答案

小编典典

在EmployeeEntityFour中的employeeCadre上,您需要一个@JoinColumn(name =“
MEMBER_ID”),并且在ProjectEntityOne employeeCadre中还需要一个@JoinColumn(name =“
PRJ_ID”)。

但是,我不会这样建模。首先,您不能具有双向ElementCollection映射,并且ElementCollection只能由一侧拥有。最好的解决方案是定义一个映射到EMP_PRJ_CADRE表的Cadre实体,并从两边都拥有一个OneToMany,并且每个边都有一个ManyToOne。

或者,您可以将ManyToMany与MapKeyColumn一起使用,但我认为最好有一个实体。

2020-11-30