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(strateg
You query on User, so Hibernate will execute a 'polymorphic query'. Since MyClubUser and HisClubUser are User objects by nature (they inherit from User), Hibernate will retrieve these kind of users as well.
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.
Why Hibernate does that [joining other tables] where my concern is only User?
Because all HisClubUser are also valid instances of User, it is logical to retrieve these when you ask for 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.
Are you really sure? Check (in debug for example) the effective class that is returned, it should be the subclasses. So down-casting could be possible, and the properties could be accessed.
Also, does this causes additional overhead as compared to a query where it just query User table without the left outer join?
Yes, and extra join has an overhead. It could be important or not : I suggest you test it in your specific case.