Hibernate继承战略和原因 [英] Hibernate Inheritance Strategy and Why
问题描述
我有3个非抽象持久化类。 MyClubUser和HisClubUser类继承自User类。对于这些类,我为每个子类策略使用一个表,即 @Inheritance(strategy = InheritanceType.JOINED)
。
我观察到的是,当我在用户类上进行查询时,生成的SQL使用左外连接HisClubUser和MyClubUser。为什么Hibernate会这样做[加入其他表]我只关心用户的问题?我的观点是,即使数据被检索到,但如果返回了User实例,我将无法访问MyClubUser或HisClubUser中的这些属性。此外,这是否会导致额外的开销,而不是查询它只是查询用户表没有左外连接?
谢谢
$ 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屋!