【问题标题】:Many-to-many one way mapping and use only two tables多对多单向映射并且只使用两个表
【发布时间】:2011-04-05 00:37:46
【问题描述】:

我有两个实体:项目、员工

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

代码:

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

Employee 和 Project 是一种单向多对多的关系。一般的做法是拥有三个表: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>     

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

【问题讨论】:

    标签: hibernate orm jpa jpa-2.0


    【解决方案1】:

    请注意,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;
        ...
    }
    

    如果您只需要 reads 支持,您可以尝试PROJECT 表本身定义为 JoinTable(我什至不确定它是否会起作用正确),但这不适用于 writes

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

    【讨论】:

    • 感谢 Pascal,请参阅 [更新]。
    • @Candy 不客气。但是,请将 new 问题作为新问题发布。如果您愿意,可以将其链接到这个,但您的更新是一个不同的问题和问题,即使相关。请不要在一个问题中混合问题。我不会在这里回答。
    • 是否可以将 @JoinColumn(name="EMPLOYEE_EMPLOYEEID" .. 映射到员工表上的另一个唯一键?我无法做到这一点。我想显示一个字符串唯一约束而不是整数
    【解决方案2】:

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

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

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

    这真的是你想要的吗?我不推荐它。

    【讨论】:

    • 我不想非规范化 Employee 表。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 2019-01-08
    • 2011-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多