1

我有一个与连接表建立的多对多关系,该连接表与 Java Persistence wiki 上描述的多对多关系注释示例完全相同. 使用员工和项目的 wiki 示例作为参考,示例中列出的代码可以很好地创建三个表:EMP、PROJ 和 EMP_PROJ 连接表。我想做的是在一个单独的实体中使用那个 EMP_PROJ 连接表。我不想在 EMP_PROJ 连接表中添加额外的列。例如,假设管理员将项目与员工相关联。该列表存储在 EMP_PROJ 中。我想做的是创建一个名为 ManagerReport 的单独实体,该实体将为员工返回与该员工关联的项目列表。然后,经理可以为员工输入有关每个项目的特定信息,例如开始日期、结束日期、绩效等。

以下是从 wiki 页面提取的表格和示例代码。

EMPLOYEE (table)
ID  FIRSTNAME   LASTNAME
1   Bob     Way
2   Sarah   Smith

EMP_PROJ (table)
EMP_ID  PROJ_ID
1   1
1   2
2   1

PROJECT (table)
ID  NAME
1   GIS
2   SIG

@Entity
public class Employee {
  @Id
  @Column(name="ID")
  private long id;
  ...
  @ManyToMany
  @JoinTable(
      name="EMP_PROJ",
      joinColumns={@JoinColumn(name="EMP_ID", referencedColumnName="ID")},
      inverseJoinColumns={@JoinColumn(name="PROJ_ID", referencedColumnName="ID")})
  private List<Project> projects;
  ...
}
4

1 回答 1

2

您必须创建一个ManagerReportProject实体,该实体映射到带有@Table注释的EMP_PROJ表。

Employee实体中,使用@OneToMany映射将集合映射到ManagerReportProject实体,而不是使用@ManyToMany映射来映射项目集合。

您仍然可以获得员工项目的列表,因为每个 ManagerReportProject 都进一步指向 Project。您甚至可以在 Employee 中创建一个帮助程序getProjects()方法来获取项目列表。方法必须用@Transient注释以将 getProjects() 方法标记为不是 JPA 持久性(默认情况下,实体映射中的所有属性或字段都是持久性的)

     @Entity
     public class Employee 
     {
          @Id
          @Column(name="ID")
          private long id;
          ...
          @OneToMany...
          private List<ManagerReportProject> managerReportProjects;
          ...

          /*
          YOU DON'T NEED THIS ANYMORE:
          @ManyToMany
          @JoinTable(
              name="EMP_PROJ",
              joinColumns={@JoinColumn(name="EMP_ID", referencedColumnName="ID")},
              inverseJoinColumns={@JoinColumn(name="PROJ_ID", referencedColumnName="ID")})
          private List<Project> projects;

           */

       @Transient
       public List<Project> getProjects()
       {
          List<Project> projects = new ArrayList<Project>();
          for(ManagerReportProject managerReportProject: managerReportProjects)
          {
             projects.add(managerReportProject.getProject());
          }
          return projects;
       }
     ...
    }

   

ManagerReportProject应该指向具有@ManyToOne关联的EmployeeProjectManager实体。 将经理报告特定列放入 ManagerReportProject (开始日期、结束日期、绩效等)。 ManagerReportProject 映射到带有@Table注释的EMP_PROJ表。

@Entity
@Table(name= "EMP_PROJ")
public class ManagerReportProject{
  @Id
  @Column(name="ID")
  private long id;

//manager report columns
  private Date startDate;
  private Date endDate;
  performance, etc. 

  @ManyToOne...
  private Manager manager;

  ...
  @ManyToOne...
  private Employee employee;

  @ManyToOne...
  private Project project;

  ...
}

   

创建一个Manager实体,使用@OneToMany将集合映射到ManagerReportProject实体:

@Entity
public class Manager {
  @Id
  @Column(name="ID")
  private long id;
  ...
  @OneToMany...
  private List<ManagerReportProject> managerReportProjects;
  ...
}

   

现在,您可以为员工输入有关每个项目的特定信息,例如开始日期、结束日期、绩效等。 这是一个草图,只是为了展示如何为为特定经理工作的特定员工编辑现有经理报告的想法:

Emyployee employee = ...
Manager manager = ...
List<ManagerReportProject> managerReportProjects= employee.getManagerReportProjects()
for(ManagerReportProject managerReportProject: managerReportProjects )
{
    if(manager.equals(managerReportProject.getManager()))
    {
       Project project = managerReportProject.getProject();

       managerReportProject.setStartDate(...);
       managerReportProject.setEndDate(...);
       managerReportProject.setperformance(...);
       ...

    }

}
于 2013-09-17T21:21:49.710 回答