使用discriminator列映射同一表中的OneToOne关系

时间:2013-06-11 07:46:37

标签: hibernate jpa orm one-to-one

我遇到的问题类似于以下结构。

实体汽车是一个抽象的实体,可以派生到CityCar,StationWagon,PickUp ... - 每辆车都有一个引擎,它是FuelEngine,DieselEngine,HybridEngine等的抽象实体......

由于这是一个识别OneToOne关系,数据库设计合并了同一个表中的两个实体(我正在手工编写以下SQL,现在我对SQL有点生疏)

CREATE TABLE CAR (
    ID UNSIGNED INT PRIMARY KEY,
    TYPE_OF_CAR CHAR,
    LICENSE_PLATE VARCHAR(...),
    ....
    ENGINE_TYPE CHAR,
    ENGINE_CYLINDRATE DECIMAL, //let's say doesn't apply to ENGINE_TYPE='ELECTRIC'
    ENGINE_KW_POWER DECIMAL(...) NOT NULL,
    ...
)

现在我想在Hibernate中映射它。我对Car类和子类的语法很有信心。目前,我的POJO如下:

@Entity
@Inheritance(SINGLE.TABLE)
@DiscriminatorColumn(TYPE_OF_CAR)
public class Car{

    private int id;

    ....

    private char engineType;
    private float engineCylindrate;

    ....

}

问题是:是否可以让POJO显示属性private Engine engine;,而不是让所有引擎属性而没有单独的引擎表? Engine类应该如何没有自己的表?

1 个答案:

答案 0 :(得分:2)

作为旁注,这样的数据库设计当然会产生大量的列,其中大部分时间都是零值:所有其他汽车的拾音器货物区域的大小,所有电动机的特定属性行等等。

数据库中的相同行无法与两个不同的JPA实体匹配。因此,如果Engine应该是实体,则需要单独的Car和Engine表。这也将导致更好的模型。

如果这不可行,还有其他方法。 JPA将属性分组为单独类的方法是使用@Embeddable。因为JPA不支持嵌入式的继承(至少在规范中没有提到,Hibernate不支持:HHH-1910),所以不能有引擎的子类型。如前所述,更好的解决方案是使用两个(至少)表。