【问题标题】:Reference key issue while doing many to many relationship using @ElementCollection, @MapKeyJoinColumn使用@ElementCollection、@MapKeyJoinColumn 进行多对多关系时参考关键问题
【发布时间】:2013-03-21 12:04:26
【问题描述】:

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

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;
   ....
   ..
   .
}

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

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 时,我也收到一个错误,因为第三个表的列不正确。

我在哪里失踪

【问题讨论】:

  • 您确定可以在同一个@CollectionTable(name="EMP_PRJ_CADRE") 中记录2 种键(ProjectEntityOne、EmployeeEntityFour)吗?
  • 是的,它是第三张表,其中包含多对多的复合键

标签: java jpa jpa-2.0 java-ee-6


【解决方案1】:

它以某种方式起作用,我不得不对代码进行一些更改,

首先,Entity ProjectEntityOne中编辑后的代码如下,

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

我在这里所做的是我在@CollectionTable 中添加了@JoinedColumn,

我在 Entity EmployeeEntityFour 中进行的第二次更改,更改是我从中删除了 PorjectEntityOne 的 Map,

在测试中, 我可以使用员工映射保存项目,但这里所有员工都应该已经保存了一个。 即地图的关键

Map<EmployeeEntityFour,String> employeeCadre;

应该已经被持久化了 而且我们可以持久化项目实体。

【讨论】:

    【解决方案2】:

    在 EmployeeEntityFour 中的employeeCadre 中,您需要@JoinColumn(name="MEMBER_ID") 并且还需要在ProjectEntityOne 中的employeeCadre 中使用@JoinColumn(name="PRJ_ID")。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-05
      • 2021-09-14
      • 2015-07-09
      • 2014-11-11
      • 2020-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多