多对多单向映射并仅使用两个表

时间:2010-08-27 21:09:18

标签: hibernate orm jpa jpa-2.0

我有两个实体:Project,Employee

  • 员工拥有主键{employeeId} +其他一些属性
  • 项目具有主键{projectId}

代码:

public class Employee {
  Long employeeId;
  String name;     
}
public class Project {
  Long projectId;
  Collection<Employee> employees;
}

员工和项目是一种单向的多对多关系。一般方法是有三个表:Employee,Project,EmployeesAssignedToProjects。

Employee
----------
employeeId (PK)
name

Project
----------
projectId (PK)

EmployeesAssignedToProjects
----------------------------
projectId (FK)
employeeId (FK)
{projectId,employeeId} (PK)

由于Project除了id之外没有其他属性,因此Project表并不是必需的。这就产生了一个问题,即如果Project实际上映射到EmployeesAssignedToProjects,应如何映射这种多对多关系。

请注意,Employee没有指向Project的指针。这里不能使用典型的mappedBy构造。

[ - 更新 - ]

问题稍微复杂一点:Project和Employee都有复合键。

  • 项目的关键是{companyId,projectId}
  • 员工的密钥是{companyId,employeeId}

我采用了3个表格。表PROJECT_EMPLOYEE有3列:companyId,employeeId,projectId。我映射到xml:

<many-to-many name="PROJECT" >
 <join-table name="PROJECT_EMPLOYEE">
  <join-column name="companyId" referenced-column-name="companyId"/>
  <join-column name="employeeId" referenced-column-name="employeeId" />
  <inverse-join-column name="companyId" referenced-column-name="companyId" />
  <inverse-join-column name="projectId" referenced-column-name="projectId" />
 </join-table>
</many-to-many>     

我收到错误抱怨公司多次出现: 收集映射中的重复列:Project.employees列:companyId

2 个答案:

答案 0 :(得分:3)

  

请注意,Employee没有指向Project的指针。这里不能使用典型的mappedBy构造。

无论如何,这无关紧要。

事实是所有ManyToMany关系都需要JoinTableJoinTable是使用@JoinTable隐式或显式定义的。

@Entity
public class Project {
    @Id
    @Column(name="PROJECTID")
    private Long projectId;

    @ManyToMany
    @JoinTable(
        name="PROJECT_EMPLOYEE",
        joinColumns={@JoinColumn(name="PROJECT_PROJECTID", referencedColumnName="PROJECTID")},
        inverseJoinColumns={@JoinColumn(name="EMPLOYEE_EMPLOYEEID", referencedColumnName="EMPLOYEEID")})
    private Collection<Employee> employees;
    ...
}

如果你只需要读取支持,你可以尝试PROJECT表本身定义为JoinTable(我甚至都不支持确保它能正常工作)但这不适用于写入

换句话说,我会坚持使用常规构造来表示数据库中的多对多关系,即使用连接表。

答案 1 :(得分:0)

鉴于您提供的类文件,您可能正在尝试将n - m关系更改为n - 0..1关系。

这可以通过删除EmployeesAssignedToProjects并通过向Employee添加projectId (FK)来对其进行非规范化来完成此操作:

Employee
----------
employeeId (PK)
projectId (FK)
name

Project
----------
projectId (PK)
这是你真正想要的吗?我不推荐它。