Inheritance Types in Hibernate
1. Table per concrete class with implicit polymorphism
2. Table per concrete class with unions (same primary key for both tables)
3. Table per class hierarchy
4. Table per subclass
1. Table per concrete class with implicit polymorphism
Here Primary key value is different for two tables.
For a query against the BillingDetails class Hibernate uses the following SQL:
select CREDIT_CARD_ID, OWNER, NUMBER, EXP_MONTH, EXP_YEAR ...
from CREDIT_CARD
select BANK_ACCOUNT_ID, OWNER, ACCOUNT, BANKNAME, ...
from BANK_ACCOUNT
@MappedSuperclass
public abstract class BillingDetails {
@Column(name = "OWNER", nullable = false)
private String owner;
...
}
@Entity
@AttributeOverride(name = "owner", column =
@Column(name = "CC_OWNER", nullable = false))
public class CreditCard extends BillingDetails {
@Id @GeneratedValue
@Column(name = "CREDIT_CARD_ID")
private Long id = null;
@Column(name = "NUMBER", nullable = false)
private String number;
...
}
2. Table per concrete class with unions
Here same primary key is shared for both tables.
...
...
Here same primary key is shared for both tables (the below one is equal configuration to union).
Super class:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class BillingDetails {
@Id @GeneratedValue
@Column(name = "BILLING_DETAILS_ID")
private Long id = null;
@Column(name = "OWNER", nullable = false)
private String owner;
...
}
Subclass:
@Entity
@Table(name = "CREDIT_CARD")
public class CreditCard extends BillingDetails {
@Column(name = "NUMBER", nullable = false)
private String number;
...
}
A query for BillingDetails executes the following SQL statement:
select
BILLING_DETAILS_ID, OWNER, NUMBER, EXP_MONTH, EXP_YEAR,ACCOUNT, BANKNAME, SWIFT CLAZZ_
from
( select BILLING_DETAILS_ID, OWNER,NUMBER, EXP_MONTH, EXP_YEAR,
null as ACCOUNT, null as BANKNAME, null as SWIFT,1 as CLAZZ_
from
CREDIT_CARD
union
select BILLING_DETAILS_ID, OWNER,null as NUMBER, null as EXP_MONTH, null as EXP_YEAR, ...ACCOUNT, BANKNAME, SWIFT,2 as CLAZZ_
from
BANK_ACCOUNT
)
3. Table per class
...
...
Super Class:
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn( name = "BILLING_DETAILS_TYPE",
discriminatorType = DiscriminatorType.STRING)
public abstract class BillingDetails {
@Id @GeneratedValue
@Column(name = "BILLING_DETAILS_ID")
private Long id = null;
@Column(name = "OWNER", nullable = false)
private String owner;
...
}
SubClass:
@Entity
@DiscriminatorValue("CC")
public class CreditCard extends BillingDetails {
@Column(name = "CC_NUMBER")
private String number;
...
}
4. Table per
...
...
Hibernate relies on an outer join when querying the BillingDetails class:
select BD.BILLING_DETAILS_ID, BD.OWNER,
CC.NUMBER, CC.EXP_MONTH, ..., BA.ACCOUNT, BA.BANKNAME, ...
case
when CC.CREDIT_CARD_ID is not null then 1
when BA.BANK_ACCOUNT_ID is not null then 2
when BD.BILLING_DETAILS_ID is not null then 0
end as CLAZZ_ from BILLING_DETAILS BD
left join CREDIT_CARD CC
on BD.BILLING_DETAILS_ID = CC.CREDIT_CARD_ID
left join BANK_ACCOUNT BA
on BD.BILLING_DETAILS_ID = BA.BANK_ACCOUNT_ID
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class BillingDetails {
@Id @GeneratedValue
@Column(name = "BILLING_DETAILS_ID")
private Long id = null;
...
}
@Entity
public class BankAccount {
...
}
This entity has no identifier property; it automatically inherits the BILLING_DETAILS_ID property and column from the superclass, and Hibernate knows how to join the tables together if you want to retrieve instances of BankAccount. Of course, you can specify the column name explicitly: