Hibernate:单表中的父/子关系 [英] Hibernate: Parent/Child relationship in a single-table

查看:140
本文介绍了Hibernate:单表中的父/子关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我几乎看不到有关Hibernate的以下问题的任何指针。这涉及使用具有父 - 子
关系的单个数据库表实现继承。例如:

$ p $ CREATE TABLE Employee(
empId BIGINT不为NULL AUTO_INCREMENT,
empName VARCHAR(100) NOT NULL,
managerId BIGINT,
CONSTRAINT pk_employee PRIMARY KEY(empId)

这里, managerId 列可以为空,或者可以指向 Employee 表的另一行。业务规则要求员工知道他所有的报告人,并要他了解他/她的经理。业务规则还允许行具有null managerId (组织的首席执行官没有经理)。



我们如何映射这种关系在Hibernate中,标准的多对一关系在这里不起作用?尤其是,如果我想将我的实体不仅作为一个相应的员工实体类来实现,而且还要实现从员工超级实体类继承的多个类,如经理,助理经理,工程师等等。 ,某些实体并不实际适用于所有实体,例如经理会得到Perks,其他实体则不会(当然,相应的表列会接受空值)。



示例代码将被赞赏(我打算使用Hibernate 3注解)。 您在这里表达了两个概念:


  1. 继承,您希望将您的继承层次结构映射到单个表中。
  2. 父/孩子的关系。

要实现1.,您需要使用Hibernate的每个类层次结构的单个表策略: @Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
name =emptype,
discriminatorType = DiscriminatorType.STRING

公共抽象类员工{...}

@实体
@ DiscriminatorValue(MGR)
公共类管理器扩展Employee {...}

要实现2.,您需要在<$ c $上添加两个自引用关联c>员工:




  • 许多员工有零个或一个经理(这也是一个员工

  • 一名员工有零个或多个reportee(s)


结果 Employee 可能如下所示:

  @Entity 
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
name =emptype,
discriminatorType = DiscriminatorType.STRING

public abstract class Employee {

...

私人员工经理;
私人套餐<员工> reportees = new HashSet< Employee>();

@ManyToOne(optional = true)
public Employee getManager(){
return manager;
}

@OneToMany
public Set< Employee> getReportees(){
return reportees;
}

...
}

这将导致下面的表:

  CREATE TABLE EMPLOYEE_EMPLOYEE(
EMPLOYEE_ID BIGINT不为NULL,
REPORTEES_ID BIGINT不为NULL
);

CREATE TABLE EMPLOYEE(
EMPTYPE VARCHAR(31)NOT NULL,
ID BIGINT NOT NULL,
NAME VARCHAR(255),
MANAGER_ID BIGINT
);

ALTER TABLE EMPLOYEE ADD CONSTRAINT SQL100311183749050 PRIMARY KEY(ID);

ALTER TABLE EMPLOYEE_EMPLOYEE ADD CONSTRAINT SQL100311183356150 PRIMARY KEY(EMPLOYEE_ID,REPORTEES_ID);

ALTER TABLE雇员添加约束FK4AFD4ACE7887BF92 FOREIGN KEY(MANAGER_ID)
REFERENCES EMPLOYEE(ID);

ALTER TABLE EMPLOYEE_EMPLOYEE ADD CONSTRAINT FKDFD1791F25AA2BE0 FOREIGN KEY(REPORTEES_ID)
REFERENCES EMPLOYEE(ID);

ALTER TABLE EMPLOYEE_EMPLOYEE ADD CONSTRAINT FKDFD1791F1A4AFCF1 FOREIGN KEY(EMPLOYEE_ID)
REFERENCES EMPLOYEE(ID);


I hardly see any pointer on the following problem related to Hibernate. This pertains to implementing inheritance using a single database table with a parent-child relationship to itself. For example:

CREATE TABLE Employee (
  empId BIGINT NOT NULL AUTO_INCREMENT,
  empName VARCHAR(100) NOT NULL,
  managerId BIGINT,
  CONSTRAINT pk_employee PRIMARY KEY (empId)
)

Here, the managerId column may be null, or may point to another row of the Employee table. Business rule requires the Employee to know about all his reportees and for him to know about his/her manager. The business rules also allow rows to have null managerId (the CEO of the organisation doesn't have a manager).

How do we map this relationship in Hibernate, standard many-to-one relationship doesn't work here? Especially, if I want to implement my Entities not only as a corresponding "Employee" Entity class, but rather multiple classes, such as "Manager", "Assistant Manager", "Engineer" etc, each inheriting from "Employee" super entity class, some entity having attributes that don't actually apply to all, for example "Manager" gets Perks, others don't (the corresponding table column would accept null of course).

Example code would be appreciated (I intend to use Hibernate 3 annotations).

解决方案

You are expressing two concepts here:

  1. inheritance and you want to map your inheritance hierarchy in a single table.
  2. a parent/child relationship.

To implement 1., you'll need to use Hibernate's single table per class hierarchy strategy:

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
    name="emptype",
    discriminatorType=DiscriminatorType.STRING
)
public abstract class Employee { ... }

@Entity
@DiscriminatorValue("MGR")
public class Manager extends Employee { ... }

To implement 2., you'll need to add two self-referencing associations on Employee:

  • many employee have zero or one manager (which is also an Employee)
  • one employee has zero or many reportee(s)

The resulting Employee may looks like this:

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
    name="emptype",
    discriminatorType=DiscriminatorType.STRING
)
public abstract class Employee { 

    ... 

    private Employee manager;
    private Set<Employee> reportees = new HashSet<Employee>();

    @ManyToOne(optional = true)
    public Employee getManager() {
        return manager;
    }

    @OneToMany
    public Set<Employee> getReportees() {
        return reportees;
    }

    ...
}

And this would result in the following tables:

CREATE TABLE EMPLOYEE_EMPLOYEE (
        EMPLOYEE_ID BIGINT NOT NULL,
        REPORTEES_ID BIGINT NOT NULL
    );

CREATE TABLE EMPLOYEE (
        EMPTYPE VARCHAR(31) NOT NULL,
        ID BIGINT NOT NULL,
        NAME VARCHAR(255),
        MANAGER_ID BIGINT
    );

ALTER TABLE EMPLOYEE ADD CONSTRAINT SQL100311183749050 PRIMARY KEY (ID);

ALTER TABLE EMPLOYEE_EMPLOYEE ADD CONSTRAINT SQL100311183356150 PRIMARY KEY (EMPLOYEE_ID, REPORTEES_ID);

ALTER TABLE EMPLOYEE ADD CONSTRAINT FK4AFD4ACE7887BF92 FOREIGN KEY (MANAGER_ID)
    REFERENCES EMPLOYEE (ID);

ALTER TABLE EMPLOYEE_EMPLOYEE ADD CONSTRAINT FKDFD1791F25AA2BE0 FOREIGN KEY (REPORTEES_ID)
    REFERENCES EMPLOYEE (ID);

ALTER TABLE EMPLOYEE_EMPLOYEE ADD CONSTRAINT FKDFD1791F1A4AFCF1 FOREIGN KEY (EMPLOYEE_ID)
    REFERENCES EMPLOYEE (ID);

这篇关于Hibernate:单表中的父/子关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆