按类型表映射子类(多对一休眠)

时间:2014-04-11 11:44:11

标签: java hibernate jpa mapping many-to-one

我必须制作拼贴项目的域层。 我们有很少的标准,比如我们必须使用Hibernate,数据库也是修复的。

数据库的相关部分看起来几乎是这样的:

BusEntitys (表1)

  • BusId
  • 巴士特定信息

BusType (表2)

  • BusTypeId
  • 座椅
  • ...
  • SubClass Discriminator

我遇到的问题是域层中有两种类型的总线由BusType-table中的鉴别器区分:

@Entity
class Bus
{
   @Id
   int _id;
   ...
}

@Entity
class BusSubClass1 extends Bus
{
   ...
}

@Entity
class BusSubClass2 extends Bus
{
   ...
}

有没有办法用Hibernate和JPA映射这样的东西? 谢谢你的每一个答案。

Jochen Morent

1 个答案:

答案 0 :(得分:2)

是的,有几种方法可以映射这种情况。 JPA为三种不同的数据表示提供支持:

  • 单桌策略
  • 加入策略
  • 每个班级的策略

换句话说,根据使用的继承类型,您将获得不同的数据库模型。各种JPA提供者可能支持其他继承策略。

考虑以下示例:

@Entity
@Inheritance //by default SINGLE_TABLE strategy
@DiscriminatorColumn( //not supported for TABLE_PER_CLASS strategy
    name = "BUS_TYPE", 
    discriminatorType = DiscriminatorType.INTEGER
)
public abstract class Bus {
    @Id
    protected int id;
    protected int seats;

    public Bus() {
    }
}

@Entity
@DiscriminatorValue(value = "1") //not supported for TABLE_PER_CLASS strategy
public class BusSubClass1 extends Bus {
    private String specific1;

    public BusSubClass1() {
    }
}

@Entity
@DiscriminatorValue(value = "2") //not supported for TABLE_PER_CLASS strategy
public class BusSubClass2 extends Bus {
    @Temporal
    private Data specific2;

    public BusSubClass2() {
    }
}

使用InheritanceType.SINGLE_TABLE策略会导致包含所有具体实体类型的单个数据库表:

 Bus

 ID BUS_TYPE SEATS SPECIFIC1 SPECIFIC2
 -- -------- ----- --------- ---------
 1  1        50    qwerty
 2  1        55    asdfgh
 3  2        30              2014-01-01
  • 继承层次结构中的每个具体实体实例都由鉴别器值区分(此处由BUS_TYPE列表示)
  • 所有数据库列必须声明为 nullable ,因为并非所有数据库列都包含值(因此对于无法设置为null的列可能会出现问题)
  • 广泛或深层次结构可能会影响性能(表中的许多冗余列或行)
  • 缺乏规范化会浪费数据库表中的空间
  • 为读写操作提供了良好的性能(多态查询不需要连接,只需要鉴别器值)
  • 添加/删除实体字段可能有问题(从数据库管理的角度来看)

使用InheritanceType.JOINED策略会导致每个实体类型有多个数据库表(来自Bus的所有共享字段都存储在相应的表中):

 Bus                        BusSubClass1          BusSubClass2

 ID BUS_TYPE SEATS          ID SPECIFIC1          ID SPECIFIC2
 -- -------- -----          -- ---------          -- ---------
 1  1        50             1  qwerty             3  2014-01-01
 2  1        55             2  asdfgh
 3  2        30
  • 继承层次结构中的每个具体实体类都由鉴别器值区分(此处由BUS_TYPE列表示)
  • 规范化可以改善数据存储(与SINGLE_TABLE策略相比,未使用的空间更少)
  • 非多态查询(针对单个具体实体)需要连接
  • 多态查询(对于实体类的广泛或深层次结构)需要多个连接并且可能很昂贵
  • 添加/删除实体字段相当简单(从数据库管理的角度来看)

使用InheritanceType.TABLE_PER_CLASS策略可以为每个实体类型提供一个数据库表(来自Bus的所有共享字段在具体子类中重新定义):

 BusSubClass1                BusSubClass2

 ID SEATS SPECIFIC1          ID SEATS SPECIFIC2
 -- ----- ---------          -- ----- ---------
 1  50    qwerty             3  30    2014-01-01
 2  55    asdfgh                     
  • 继承层次结构中的每个具体实体类仅由共享标识符区分(不使用鉴别​​符)
  • 规范化可以改善数据存储(与SINGLE_TABLE策略相比,未使用的空间更少,但比JOINED策略更多)
  • 非多态查询(对于单个具体实体)是高效的,因为不需要连接
  • 多态查询(对于实体类的广泛或深层次结构)需要多个连接并且可能很昂贵
  • 添加/删除实体字段很简单(从数据库管理的角度来看)