Hibernate - 继承中的外键和主键

时间:2015-11-16 09:36:39

标签: java mysql hibernate

我在想,是否有可能有这样的事情。假设我有一个名为material的表:

+-------+---------------+------+-----+---------+-------+
| Field | Type          | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| id    | int(11)       | NO   | PRI | NULL    |       |
| name  | varchar(255)  | YES  |     | NULL    |       |
| price | decimal(19,2) | YES  |     | NULL    |       |
+-------+---------------+------+-----+---------+-------+

在Java端实体将是:

@Entity
@DiscriminatorValue("M")
public class Material extends Expense {

    private String name;

    private BigDecimal price;

    // Getters and setters
}

和名为occupation的表:

+--------------+---------------+------+-----+---------+-------+
| Field        | Type          | Null | Key | Default | Extra |
+--------------+---------------+------+-----+---------+-------+
| id           | int(11)       | NO   | PRI | NULL    |       |
| name         | varchar(255)  | YES  |     | NULL    |       |
| payment_type | varchar(255)  | YES  |     | NULL    |       |
| price        | decimal(19,2) | YES  |     | NULL    |       |
+--------------+---------------+------+-----+---------+-------+

在Java端实体将是:

@Entity
@DiscriminatorValue("O")
public class Occupation extends Expense {

    private String name;

    private BigDecimal price;

    @Enumerated(EnumType.STRING)
    private PaymentType paymentType;

    // Getters and setters

}

现在假设我想在Java端创建一个名为Occupation的{​​{1}}和Material的公共类,它将代表材料和职业的费用。这看起来像这样:

Expense

在SQL端:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "expense_type", discriminatorType = DiscriminatorType.STRING)
public class Expense {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    // Getters and setters

}

然而,问题是当我们引入继承时,费用的主键是物料和占用表中的外键。是否有可能费用表有自己的主键,并以某种方式保存材料和职业的id和鉴别器类型,以便材料和职业表可以具有相同id的行(如+--------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+-------------+------+-----+---------+----------------+ | expense_type | varchar(31) | NO | | NULL | | | id | int(11) | NO | PRI | NULL | auto_increment | +--------------+-------------+------+-----+---------+----------------+ id在材料和{{1}职业表中的id)?我的意思是,在SQL方面它可以很容易地完成,但是Java方面呢?

2 个答案:

答案 0 :(得分:1)

根据hibernate文档,尝试:

  

@PrimaryKeyJoinColumn和@PrimaryKeyJoinColumns注释   定义连接的子类表的主键:

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class Boat implements Serializable { ... }

@Entity
@PrimaryKeyJoinColumn(name="BOAT_ID")
public class AmericaCupClass  extends Boat { ... }    

https://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#d0e1168

另请参阅PrimaryKeyJoinColumn javadoc,它有:

  

(可选)表的主键列的名称   加入了。默认为与主键列相同的名称   超类的主表(JOINED映射   战略);与主要主键列相同的名称   table(SecondaryTable mapping);或与...相同的名称   引用实体的表的主键列   (OneToOne映射)。

     

String referencedColumnName()

我认为这就是你需要的东西

答案 1 :(得分:-1)

根据JPA 2.0规范,这是不可能的。它在2.4节(主键和实体标识)中说:

  

主键必须在作为实体层次结构的根或在a上的实体类上定义   映射的超类,它是实体层次结构中所有实体类的(直接或间接)超类。该   主键必须在实体层次结构中只定义一次。