Hibernate继承战略和原因 [英] Hibernate Inheritance Strategy and Why

查看:95
本文介绍了Hibernate继承战略和原因的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我观察到的是,当我在用户类上进行查询时,生成的SQL使用左外连接HisClubUser和MyClubUser。为什么Hibernate会这样做[加入其他表]我只关心用户的问题?我的观点是,即使数据被检索到,但如果返回了User实例,我将无法访问MyClubUser或HisClubUser中的这些属性。此外,这是否会导致额外的开销,而不是查询它只是查询用户表没有左外连接?



谢谢

ALWAYS 返回实际类型的持久化实体。如果您存储了MyClubUser,它将作为MyClubUser返回,而不是用户。原因很明显 - 如果Hibernate将MyClubUser作为用户返回并且您要再次坚持下去,您将失去MyClubUser中定义的所有其他属性。


$ b $为了做到这一点,Hibernate需要知道实际类型是什么。对于 InheritanceType.JOINED 策略,唯一的方法是检查继承层次结构中的所有表格(从技术上讲,所有表格都是或低于当前级别加当前树分支中当前级别之上的所有表)。所以,如果你有一个层次结构:

$ $ p $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ Node $ Node $
/ \
Node11 Node12

你试图从root中选择Hibernate将在所有表上执行外连接。如果您从Node1中选择,Hibernate将在Node1和Root上进行内连接,并在Node11和Node12上执行外连接。 Node2不会被触及,因为它不是Node1的后裔。



就外连接开销而言 - 是的,肯定会有开销,但这是您付出的代价加入战略。你可以使用鉴别器来避免这种情况,但是它带有自己的副作用。这种开销是否显着取决于层次结构的深度和分布,索引以及其他许多事情。聆听KLE的建议并分析它。


I have 3 non-abstract persist-able classes. MyClubUser and HisClubUser classes inherit from User class. I use one table per subclass strategy i.e. @Inheritance(strategy = InheritanceType.JOINED), for these classes.

What I have observed was the generated SQL uses left outer join HisClubUser and MyClubUser when I do a query on User class. Why Hibernate does that [joining other tables] where my concern is only User? My point is even though the data is retrieved, I would not able to access these properties in MyClubUser or HisClubUser given that User instances are returned. Also, does this causes additional overhead as compared to a query where it just query User table without the left outer join?

Thanks

解决方案

Hibernate ALWAYS returns the actual type of persisted entity. If you've stored "MyClubUser" it will be returned as "MyClubUser", never as "User". The reason for this is quite clear - if Hibernate were to return "MyClubUser" as "User" and you were to persist it again you would lose all additional properties defined in "MyClubUser".

In order to do that, Hibernate needs to know what that actual type is. For InheritanceType.JOINED strategy the only way to find that out is to check all the tables in your inheritance hierarchy (well, technically it's all tables at or below current level plus all tables above current level in current tree branch). So, if you have a hierarchy like:

           Root
          /   \
      Node1  Node2
      /   \
   Node11 Node12

and you're trying to select from root, Hibernate will do an outer join on ALL tables. If you're selecting from Node1, Hibernate will do an inner join on Node1 and Root plus an outer join on Node11 and Node12. Node2 won't be touched because it's not a descendant of Node1.

As far as outer join overhead goes - yes, there's definitely an overhead but that's the price you pay for joined strategy. You can use discriminators to avoid this but that comes with its own side effects. Whether that overhead is significant or not depends on the depth and spread of your hierarchy, your indexes and many other things. Listen to KLE's suggestion and profile it.

这篇关于Hibernate继承战略和原因的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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