如何使用JPA注解混合策略的继承和Hibernate? [英] How to mix inheritance strategies with JPA annotations and Hibernate?

查看:336
本文介绍了如何使用JPA注解混合策略的继承和Hibernate?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

按照 Hibernate参考文档的应该是可能使用Hibernate XML的元数据时,混合不同的继承映射策略:结果
<一href=\"http://docs.jboss.org/hibernate/stable/core/reference/en/html/inheritance.html#inheritance-mixing-tableperclass-tablepersubclass\">http://docs.jboss.org/hibernate/stable/core/reference/en/html/inheritance.html#inheritance-mixing-tableperclass-tablepersubclass

然而,相应部分的 Hibernate注解参考指南的不涵盖:结果
<$c$c>http://docs.jboss.org/hibernate/stable/annotations/reference/en/html/entity.html#d0e1168

在另一方面,所述的JavaDoc表明混合继承战略应是可能的。例如,在javax.persistence.DiscriminatorColumn它说:


  

策略和鉴别列只在实体类层次或子层级中,不同的继承策略应用的根指定的。



以下是我想要实现的映射的例子。我想使用的的层次结构的根表附近的每个子类的映射,但改变的表每类层次结构的映射叶子附近。下面是一些例子code:

  @Entity
@Inheritance(策略= InheritanceType.JOINED)
公共抽象A类实现Serializable
{
    @ID
    私人字符串ID;    //其他映射属性...
}@实体
@Inheritance(策略= InheritanceType.SINGLE_TABLE)
公共类BB延伸
{
    //其他映射属性和协会...
}@实体
公共类BB1扩展BB
{
    //其他的东西,不一定要映射...
}@实体
公共类BB2扩展BB
{
    //其他的东西,不一定要映射...
}@实体
@Inheritance(策略= InheritanceType.SINGLE_TABLE)
公共类CC的延伸
{
    //其他映射属性和协会...
}@实体
公共类CC1扩展CC
{
    //其他的东西,不一定要映射...
}...

我是从这个映射想到的是有确切3个表什么: A BB CC 。无论 BB CC 应该叫一个默认的鉴别列 DTYPE 。他们也应该提供必要的所有列在各自的子类映射的所有属性和关联。

相反,类层次结构似乎使用的表每个子类的继承整个战略。即我得到一个自己的表中的每个上面提到的实体。我想避免这种情况,因为类层次结构的叶子是非常轻的重量和它只是似乎矫枉过正有一个单独的表中的每个人!


难道我忽略的东西吗?任何意见是高度AP preciated!我很乐意提供额外的信息...


解决方案

  

根据使用Hibernate XML的元数据(......)时,它应该是可以混合不同的继承映射策略Hibernate参考文档


其实,这不是的真正的支持,他们是作弊使用辅助表,从文档的例子中,单表策略切换。引用的 Java持久性与Hibernate 的:


  

您可以映射整个继承
  通过嵌套层次
  &LT;工会子&GT; &LT;子类&GT;
  和&LT;加入了子类&GT; 映射
  元素。不能混合它们了 -
  例如,从一个切换
  表每类层次结构与
  鉴别器来归一化
  表每个子类的策略。 一旦
  你已经做出了决定为
  继承策略,你必须
  坚持下去


  
  

这是不完全是这样,但是。
  对于某些Hibernate的小技巧,就能
  切换的映射策略
  特别是子类。例如,
  可以一个类层次结构映射到单个
  表,但对于特定的子类,
  切换到一个单独的表与
  外键映射策略
,就像
  每个子类表。这是
  可能与&LT;&加盟GT; 映射
  元素:

 &LT;休眠映射&GT;
  &LT;类名=BillingDetails
      表=BILLING_DETAILS&GT;    &LT;&ID GT; ...&LT; / ID&GT;    &LT;鉴别
        列=BILLING_DETAILS_TYPE
        类型=字符串/&GT;
    ...
    &LT;子
        NAME =信用卡式
        鉴别值=CC&GT;
      &LT;连接表=CREDIT_CARD&GT;
        &LT;键列=CREDIT_CARD_ID/&GT;        &LT;属性名=号码一栏=CC_NUMBER/&GT;
        &LT;属性名=expMonth栏=CC_EXP_MONTH/&GT;
        &LT;属性名=expYear栏=CC_EXP_YEAR/&GT;
        ...
      &LT; /加入&GT;
    &LT; /子&GT;    &LT;子
        NAME =的BankAccount
        鉴别值=BA&GT;
      &LT;属性名=账户一栏=BA_ACCOUNT/&GT;
      ...
    &LT; /子&GT;
  ...
  &LT; /班&GT;
&LT; /休眠映射&GT;


和可以达到同样的用注解:


  

Java持久性也支持此注释混合遗传映射策略。地图超 BillingDetails InheritanceType.SINGLE_TABLE ,像之前。现在,映射你想打破了单一的表来辅助表的子类。

  @Entity
@DiscriminatorValue(CC)
@SecondaryTable(
    NAME =CREDIT_CARD
    pkJoinColumns = @PrimaryKeyJoinColumn(NAME =CREDIT_CARD_ID)

公共类信用卡式扩展BillingDetails {
    @Column(表=CREDIT_CARD
        NAME =CC_NUMBER
        可空= FALSE)
    私人串号;
    ...
}


我没有测试这一点,但你也许可以尝试:


  • 地图使用SINGLE_TABLE策略

  • 地图BB,CC等使用 @SecondaryTable 注释。

我没有测试过这一点,我不知道它是否会为BB1做工精良,BB2。

参考


  • Java持久性与Hibernate

    • 5.1.5混合继承策略(P207-P210)


According to the Hibernate Reference Documentation it should be possible to mix different inheritance mapping strategies when using Hibernate's XML-Metadata:
http://docs.jboss.org/hibernate/stable/core/reference/en/html/inheritance.html#inheritance-mixing-tableperclass-tablepersubclass

However, the corresponding section of the Hibernate Annotations Reference Guide does not cover that:
http://docs.jboss.org/hibernate/stable/annotations/reference/en/html/entity.html#d0e1168

On the other hand, the JavaDocs suggest that mixing inheritance strategies should be possible. For instance in javax.persistence.DiscriminatorColumn it says:

The strategy and the discriminator column are only specified in the root of an entity class hierarchy or subhierarchy in which a different inheritance strategy is applied.


The following is an example for the mapping I'm trying to achieve. I'd like to use table-per-subclass mapping near the root of the hierarchy, but change to table-per-class-hierarchy mapping near the leaves. Here's some example code:

@Entity
@Inheritance( strategy = InheritanceType.JOINED )
public abstract class A implements Serializable
{
    @Id
    private String id;

    // other mapped properties...
}

@Entity
@Inheritance( strategy = InheritanceType.SINGLE_TABLE )
public class BB extends A
{
    // other mapped properties and associations...
}

@Entity
public class BB1 extends BB
{
    // other stuff, not necessarily mapped...
}

@Entity
public class BB2 extends BB
{
    // other stuff, not necessarily mapped...
}

@Entity
@Inheritance( strategy = InheritanceType.SINGLE_TABLE )
public class CC extends A
{
    // other mapped properties and associations...
}

@Entity
public class CC1 extends CC
{
    // other stuff, not necessarily mapped...
}

...

What I expect from this mapping is having exactly 3 tables: A, BB, and CC. Both BB and CC should have a default discriminator column called DTYPE. They should also provide all columns necessary for all mapped properties and associations of their respective subclasses.

Instead , the class hierarchy seems to use the table-per-subclass inheritance strategy throughout. I.e. I get an own table for each of the entities mentioned above. I'd like to avoid this, since the leaves of the class-hierarchy are extremely light-weight and it just seems overkill to have a separate table for each of them!


Did I overlook something? Any advice is highly appreciated! I'll be glad to provide additional info...

解决方案

According to the Hibernate Reference Documentation it should be possible to mix different inheritance mapping strategies when using Hibernate's XML-Metadata (...)

Actually, it's not really supported, they are "cheating" using a secondary table to switch from the single table strategy in the example of the documentation. Quoting Java Persistence with Hibernate:

You can map whole inheritance hierarchies by nesting <union-subclass>, <sub- class>, and <joined-subclass> mapping elements. You can’t mix them — for example, to switch from a table-per-class hierarchy with a discriminator to a normalized table-per-subclass strategy. Once you’ve made a decision for an inheritance strategy, you have to stick to it.

This isn’t completely true, however. With some Hibernate tricks, you can switch the mapping strategy for a particular subclass. For example, you can map a class hierarchy to a single table, but for a particular subclass, switch to a separate table with a foreign key mapping strategy, just as with table per subclass. This is possible with the <join> mapping element:

<hibernate-mapping>
  <class name="BillingDetails"
      table="BILLING_DETAILS">

    <id>...</id>

    <discriminator
        column="BILLING_DETAILS_TYPE"
        type="string"/>
    ...
    <subclass
        name="CreditCard"
        discriminator-value="CC">
      <join table="CREDIT_CARD">
        <key column="CREDIT_CARD_ID"/>

        <property name="number" column="CC_NUMBER"/>
        <property name="expMonth" column="CC_EXP_MONTH"/>
        <property name="expYear" column="CC_EXP_YEAR"/>
        ...
      </join>
    </subclass>

    <subclass
        name="BankAccount"
        discriminator-value="BA">
      <property name=account" column="BA_ACCOUNT"/>
      ...
    </subclass>
  ...
  </class>
</hibernate-mapping>

And you could achieve the same with annotations:

Java Persistence also supports this mixed inheritance mapping strategy with annotations. Map the superclass BillingDetails with InheritanceType.SINGLE_TABLE, as you did before. Now map the subclass you want to break out of the single table to a secondary table.

@Entity
@DiscriminatorValue("CC")
@SecondaryTable(
    name = "CREDIT_CARD",
    pkJoinColumns = @PrimaryKeyJoinColumn(name = "CREDIT_CARD_ID")
)
public class CreditCard extends BillingDetails {
    @Column(table = "CREDIT_CARD",
        name = "CC_NUMBER",
        nullable = false)
    private String number;
    ...
}

I didn't test this but you could maybe try to:

  • map A using a SINGLE_TABLE strategy
  • map BB, CC, etc using the @SecondaryTable annotation.

I've not tested this, I don't know if it will work well for BB1, BB2.

Reference

  • Java Persistence with Hibernate
    • 5.1.5 Mixing inheritance strategies (p207-p210)

这篇关于如何使用JPA注解混合策略的继承和Hibernate?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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