Reputation: 5076
if I have
@Inheritance(strategy = InheritanceType.JOINED)
Organization{
}
Account extends Organization{
private Organization organization
}
Client extends Organization{
private Organization organization
}
User {
private Organization organization
}
When I call userDAO.get(1) and get back an instance of User, how does hibernate know to give me back an instance of Account rather than Client?
Upvotes: 1
Views: 1197
Reputation: 1569
NOTE: Applies to SINGLE_TABLE
strategy only, see @Tomazs' response for JOINED
strategy.
Hibernate stores the explicit subclass used as some form of enumeration, generally as a string value, in the database. You can set the name of this column using the @DescriminatorColumn
annotation, and then use the @DiscriminatorValue
annotation on subclasses. When Hibernate goes to store an Account
in the database, any rows which are specific to say, Client
, are still stored for that Account
but are set to null
, and the DiscriminatorColumn
is set to "Account"
. Then, when the organization is deserialized, Hibernate looks at that DiscriminatorColumn
, sees that the Organization
is an Account
, and gives you back that type of object.
The DescriminatorColumn
can be changed to use other types of data, eg. not strings, using the columnDefinition
parameter. By default the name of this column is DTYPE
, and values for classes which do not have a DiscriminatorValue
are the name of the class.
Upvotes: 0
Reputation: 340753
Hibernate performs an OUTER JOIN
with every child table:
SELECT *,
case
when a.id is not null then 0
when c.id is not null then 1
when u.id is not null then 2
end as clazz
FROM Organization o
OUTER JOIN Account a
OUTER JOIN Client c
OUTER JOIN User u
And determines the actual type by looking at which OUTER JOIN
actually returned something. Obviously there will be exactly one table from Account
, Client
and User
holding a record that has the same id
- and this denotes the actual type. This is what the awkward case
/when
does.
If the discriminator column is present, OUTER JOIN
s are still needed, but it is easier to determine the actual type, as it is explicitly stored in the database. No case
/when
magic.
As you can see this inheritance strategy is very inefficient. It is much better when you explicitly ask for a given subtype, because Hibernate will do an JOIN
with only a single table.
Upvotes: 2
Reputation: 597114
For each record hibernate can store an additional (discriminator) column in the main table that indicates which type is used.
Upvotes: 1