按类型表(多对一休眠)映射子类 [英] Mapping Sub-Classes by Type Table (Many-To-One Hibernate)

查看:176
本文介绍了按类型表(多对一休眠)映射子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须制作一个拼贴项目的领域层。
我们有很少的标准,就像我们必须使用Hibernate一样,数据库也是修复的。



数据库的相关部分看起来像这样: (表1)


  • BusId li>
  • 公交车具体信息


BusType (表2)




  • BusTypeId

  • 座位

  • ...

  • 子类别判别符



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

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

@实体
类BusSubClass1扩展总线
{
...
}

@Entity
class BusSubClass2 extends Bus
{
...
}

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



Jochen Morent

解决方案

是的,映射这种情况的方法很少。 JPA提供三种不同数据表示形式的支持:
$ b $ ul

  • single-table 策略

  • 已加入策略

  • 每个班级策略


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

    考虑下面的例子:

      @Entity 
    @Inheritance //默认情况下SINGLE_TABLE策略
    @DiscriminatorColumn(//不支持TABLE_PER_CLASS策略
    name =BUS_TYPE,
    discriminatorType = DiscriminatorType.INTEGER

    public abstract class Bus {
    @Id
    protected int id;
    保护int座位;

    公共巴士(){
    }
    }

    @实体
    @ DiscriminatorValue(值=1)//不支持对于TABLE_PER_CLASS策略
    public class BusSubClass1 extends Bus {
    private String specific1;

    公共BusSubClass1(){
    }
    }

    @实体
    @ DiscriminatorValue(值=2)//不支持对于TABLE_PER_CLASS策略
    public class BusSubClass2 extends Bus {
    @Temporal
    private data specific2;

    公共BusSubClass2(){
    }
    }



    < hr>

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

     公共汽车

    ID BUS_TYPE SEATS SPECIFIC1 SPECIFIC2
    - -------- ----- --------- ---------
    1 1 50 qwerty
    2 1 55 asdfgh
    3 2 30 2014-01-01




    • 继承层次结构中的每个具体实体实例都通过鉴别器值进行区分(这里用BUS_TYPE列)所有数据库列必须声明为可空,因为它们不都可能包含值(因此对于不能设置为空的列可能会产生问题)

    • 广泛或较深的层次结构可能会影响性能(表中分别存在大量冗余列或行)
    • 缺少标准化会浪费spa数据库表中的数据库
    • 为读写操作提供了良好的性能(多态查询不需要连接,只有鉴别器值)
    • 添加/删除实体字段可能有问题(从数据库管理的角度来看)





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

      Bus BusSubClass1 BusSubClass2 
    $ b $ ID 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 的所有共享字段在具体:

    $ $ p $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ---- --------- - ----- ---------
    1 50 qwerty 3 30 2014-01-01
    2 55 asdfgh




    • 继承层次结构中的每个具体实体类仅由共享标识符未使用)

    • 规范化改进了数据存储(与SINGLE_TABLE策略相比,更少的未使用空间,但超过了JOINED策略的情况)

    • 非 - 多态查询(对于单个具体实体)效率很高,因为不需要连接。
    • 多态查询(对于实体类的广泛或深层次结构)需要多个连接并且可能很昂贵
    • >
    • 添加/删除实体字段非常简单(从数据库管理的角度来看)


    I have to make the domain-layer of a collage project. We have few standards, like we have to use Hibernate and the database also is fix.

    The relevant part of the database looks nearly like that:

    BusEntitys (Table 1)

    • BusId
    • Bus specific information

    BusType (Table 2)

    • BusTypeId
    • Seats
    • ...
    • SubClass Discriminator

    The problem I have is that there are 2 types of buses in the domain-layer distinguish by the discriminator in the BusType-table:

    @Entity
    class Bus
    {
       @Id
       int _id;
       ...
    }
    
    @Entity
    class BusSubClass1 extends Bus
    {
       ...
    }
    
    @Entity
    class BusSubClass2 extends Bus
    {
       ...
    }
    

    Is there a way to map something like this with Hibernate and JPA? Thanks for every answer.

    Jochen Morent

    解决方案

    Yes, there are few ways to map such scenario. JPA provides support for three different data representations:

    • single-table strategy
    • joined strategy
    • table-per-class strategy

    In other words depending on inheritance type used you will get different database model. Various JPA providers may support additional inheritance strategies.

    Consider the following example:

    @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() {
        }
    }
    


    Using InheritanceType.SINGLE_TABLE strategy leads to a single database table containing all concrete entity types:

     Bus
    
     ID BUS_TYPE SEATS SPECIFIC1 SPECIFIC2
     -- -------- ----- --------- ---------
     1  1        50    qwerty
     2  1        55    asdfgh
     3  2        30              2014-01-01
    

    • every concrete entity instance in the inheritance hierarchy is distinguished by discriminator value (here indicated by BUS_TYPE column)
    • all database columns must be declared as nullable because not all of them may contain values (thus may be problematic for columns that cannot be set to null)
    • wide or deep hierarchy may affect performance (a lot of redundant columns or rows respectively in a table)
    • lack of normalization can waste space in database table
    • offers good performance for read and write operations (polymorphic queries don't require joins, only discriminator value)
    • adding/removing entity fields may be problematic (from database administration point of view)

    Using InheritanceType.JOINED strategy leads to multiple database tables per entity type (all shared fields from Bus are stored in the corresponding table):

     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
    

    • every concrete entity class in the inheritance hierarchy is distinguished by the discriminator value (here indicated by BUS_TYPE column)
    • normalization improves data storage (less unused space in comparison to SINGLE_TABLE strategy)
    • non-polymorphic queries (for a single concrete entity) require a join
    • polymorphic queries (for wide or deep hierarchy of entity classes) require multiple joins and may be expensive
    • adding/removing entity fields is rather straightforward (from database administration point of view)

    Using InheritanceType.TABLE_PER_CLASS strategy leads to exqactly one database table per entity type (all shared fields from Bus are redefined in the concrete subclasses):

     BusSubClass1                BusSubClass2
    
     ID SEATS SPECIFIC1          ID SEATS SPECIFIC2
     -- ----- ---------          -- ----- ---------
     1  50    qwerty             3  30    2014-01-01
     2  55    asdfgh                     
    

    • every concrete entity class in the inheritance hierarchy is distinguished only by the shared identifier (the discriminator is not used)
    • normalization improves data storage (less unused space in comparison to SINGLE_TABLE strategy, but more than in case of JOINED strategy)
    • non-polymorphic queries (for a single concrete entity) are efficient as join is not required
    • polymorphic queries (for wide or deep hierarchy of entity classes) require multiple joins and may be expensive
    • adding/removing entity fields is straightforward (from database administration point of view)

    这篇关于按类型表(多对一休眠)映射子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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