一尘不染

休眠继承策略及其原因

hibernate

我有3个非抽象的可持久类。MyClubUser和HisClubUser类从User类继承。@Inheritance(strategy = InheritanceType.JOINED)对于每个类,我为每个子类策略使用一张表。

我观察到的是,当我对User类进行查询时,生成的SQL使用左外部联接HisClubUser和MyClubUser。为什么Hibernate在我仅关注User的情况下[加入其他表]?我的观点是,即使检索到数据,鉴于返回了用户实例,我也无法访问MyClubUser或HisClubUser中的这些属性。此外,与仅查询User表而不使用左外部联接的查询相比,这是否会导致额外的开销?

谢谢


阅读 222

收藏
2020-06-20

共1个答案

一尘不染

hibernate 总会 返回持久实体的 实际 类型。如果您已存储“ MyClubUser”,它将以“ MyClubUser”的形式返回,而不会以“
User”的形式返回。原因很明确-如果Hibernate将“ MyClubUser”作为“用户”返回,而您再次坚持下去,则会丢失“
MyClubUser”中定义的所有其他属性。

为了做到这一点,Hibernate需要知道实际的类型是什么。对于InheritanceType.JOINED策略发现的唯一方法是检查 所有
在你的继承层次结构表(当然,在技术上它是等于或低于当前水平的所有表再加上目前的树枝高于目前水平的所有表)。因此,如果您具有类似以下的层次结构:

           Root
          /   \
      Node1  Node2
      /   \
   Node11 Node12

并且您尝试从根目录中进行选择,Hibernate将对所有表进行外部联接。如果从Node1中选择,则Hibernate将在Node1和Root上进行内部联接,再在Node11和Node12上进行外部联接。Node2不会被触摸,因为它不是Node1的后代。

就外部连接开销而言-
是的,肯定有开销,但这就是您为连接策略付出的代价。您可以使用区分符来避免这种情况,但这有其自身的副作用。该开销是否显着取决于层次结构的深度和范围,索引以及许多其他事情。听取KLE的建议并进行介绍。

2020-06-20