如何将继承策略与 JPA 注解和 Hibernate 混合使用?
根据 Hibernate 参考文档,在使用 Hibernate 的 XML 元数据时应该可以混合不同的继承映射策略:
http://docs .jboss.org/hibernate/stable/core/reference/en/html/inheritance.html#inheritance-mixing-tableperclass-tablepersubclass
但是,Hibernate Annotations Reference Guide 的相应部分不包括:http://docs.jboss.org/hibernate/stable/annotations/reference/en/html/entity.html#d0e1168
另一方面,JavaDocs 建议混合继承策略应该是可能的。例如在 javax.persistence.DiscriminatorColumn 中它说:
策略和鉴别器列仅在应用不同继承策略的实体类层次结构或子层次结构的根中指定。
以下是我试图实现的映射的示例。我想在层次结构根部附近使用每个子类一个表映射,但在叶子附近更改为每个类层次结构一个表映射。下面是一些示例代码:
@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...
}
...
我期望从该映射中得到正好 3 个表:A
、BB
和 CC
。 BB
和 CC
都应该有一个名为 DTYPE
的默认鉴别器列。它们还应该提供其各自子类的所有映射属性和关联所需的所有列。
相反,类层次结构似乎自始至终都使用每个子类一个表继承策略。即我为上面提到的每个实体都有一个自己的表。我想避免这种情况,因为类层次结构的叶子非常轻量,并且为每个叶子都有一个单独的表似乎有点过分了!
我是不是忽略了什么?任何建议都将受到高度赞赏!我很乐意提供更多信息...
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...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
实际上,它并不真正支持,它们使用辅助表“作弊”从文档示例中的单表策略切换。引用Java Persistence with Hibernate:
你也可以通过注释实现同样的效果:
我没有对此进行测试,但您也许可以尝试:
@SecondaryTable
注释映射 BB、CC 等。我没有测试过这个,我不知道它是否适用于 BB1、BB2。
参考
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:
And you could achieve the same with annotations:
I didn't test this but you could maybe try to:
@SecondaryTable
annotation.I've not tested this, I don't know if it will work well for BB1, BB2.
Reference
为了清楚起见,这里是将帕斯卡的解决方案应用于我的问题中的示例代码:
我已经成功地将这种方法应用于我的问题,并且我将暂时坚持使用它。然而,我仍然看到以下缺点:
鉴别器列位于层次结构的主表中,即根实体
A
的表中。就我而言,在辅助表BB
和CC
中包含鉴别器列就足够了。每当向
BB
或CC
的子类添加属性和关联时,他/她都必须指定它们应映射到相应的辅助表。如果有一种方法可以将其设置为默认值,那就太好了。Just for the sake of clarity, here is Pascal's solution applied to the example code from my question:
I've successfully applied this approach to my problem, and I'll stick to it for the time being. However I still see the following disadvantages:
The discriminator column is located in the main table for the hierarchy, the table for root-enity
A
. In my case, it would be sufficient to have the discriminator column in the secondary tablesBB
andCC
.Anytime one adds properties and associations to subclasses of
BB
orCC
, he/she has to specify that they should be mapped to the respective secondary table. Would be nice, if there was a way to make that the default.