0% found this document useful (0 votes)
5 views

Module 05 - Hibernate Inheritance-upd

Uploaded by

surafelbehailu90
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

Module 05 - Hibernate Inheritance-upd

Uploaded by

surafelbehailu90
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 26

Module 05: Inheritance Mapping

CS544: Enterprise Architecture

© 2014 Time2Master 1
Inheritance
 Using inheritance a class can extend another class
 Thereby inheriting all its properties and method
 Often referred to as an ‘is-a’ relationship
Account is an <<abstract>>
Account
abstract class +number
+balance Checking Account
is an Account

Savings Account
also has a number SavingsAccount CheckingAccount

and a balance +APY +overdraftLimit

 Relational databases don’t have ‘is-a’ relationships


 There are 3 different ways to emulate inheritance

© 2014 Time2Master 2
Polymorphism
 Polymorphism is the ability of a subtype to
appear and behave like its supertype
 This enables Person to have a list of Account
references, which may hold SavingsAccounts
and CheckingAccounts.
 A polymorphic query is a query for all objects
in a hierarchy, independent of their subtype
Person <<abstract>>
owns Account
+firstName
+lastName +number
1 1..*
+balance
Checking Account is an Account
and can be treated as such

SavingsAccount CheckingAccount
+APY +overdraftLimit
© 2014 Time2Master 3
Three ways to map
 You can map inheritance in one of three ways:
 Single Table per Hierarchy <<abstract>>
Account
+number

 De-normalized schema
+balance

 Fast polymorphic queries SavingsAccount CheckingAccount


+APY +overdraftLimit

 Joined Tables
 Normalized & similar to classes
 Slower queries

 Table per Concrete Class


 Uses UNION instead of JOIN
 All needed columns in each table
© 2014 Time2Master 4
Inheritance Mapping

SINGLE TABLE PER HIERARCHY

© 2014 Time2Master 5
Single Table Implementation
 Single Table per Hierarchy uses one big table
 Discriminator column specifies actual type
 Sub class properties added as nullable columns

<<abstract>>
Account
+number
+balance Account type
specifies the
actual type
APY and overdraft
SavingsAccount CheckingAccount limit are nullable
+APY +overdraftLimit

© 2014 Time2Master 6
Single Table in Action

APY is null for checking


accounts, overdraft
limit is null for savings

+ Simple, Easy to implement


+ Good performance on all queries, polymorphic
and non polymorphic
– Nullable columns / de-normalized schema
– Table may have to contain lots of columns

© 2014 Time2Master 7
SQL for Single Table
select
account0_.number as number0_,
account0_.balance as balance0_,
account0_.owner_id as owner6_0_,
account0_.overdraftLimit as overdraf4_0_,
account0_.APY as APY0_,
account0_.account_type as account1_0_
from
Account account0_

© 2014 Time2Master 8
Single Table Mapping
Specify the SINGLE_TABLE strategy
@Entity
<<abstract>>
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) Account
@DiscriminatorColumn( +number
name="account_type", +balance
discriminatorType=DiscriminatorType.STRING
)
public abstract class Account { Optional annotation
@Id
@DiscriminatorColumn SavingsAccount CheckingAccount
@GeneratedValue
private long number; +APY +overdraftLimit

private double balance;

...

@Entity
@DiscriminatorValue(“savings") Specify discriminator value
public class SavingsAccount extends Account {
private double APY;

...

@Entity
@DiscriminatorValue(“checking") Specify discriminator value
public class CheckingAccount extends Account {
private double overdraftLimit;

...
© 2014 Time2Master 9
XML
<hibernate-mapping package="single">
<class name="Account" abstract="true"> Abstract account class
<id name="number">
<generator class="native" />
</id>
<discriminator> tag has to be
<discriminator type="string" column="account_type" /> after <id> and before <property>

<property name="balance" /> Account properties


<subclass name="SavingsAccount" discriminator-value="savings">
<property name="APY" />
</subclass>
Subclass definition
included inside superclass
<subclass name="CheckingAccount" discriminator-value="checking">
<property name="overdraftLimit" />
</subclass> Discriminator values optional
</class>
</hibernate-mapping>
<<abstract>>
Account
+number
+balance

SavingsAccount CheckingAccount
+APY +overdraftLimit

© 2014 Time2Master 10
Inheritance Mapping

JOINED TABLES

© 2014 Time2Master 11
Joined Tables Implementation
 The Joined Tables Strategy uses FK ‘has a’
relations to emulate ‘is a’ relations
 Uses Foreign Key constraints on the Primary Keys
 Queries use JOINs to included needed tables

<<abstract>> CheckingAccount’s
Account
primary key has a FK
+number
+balance constraint to Account

SavingsAccount CheckingAccount
+APY +overdraftLimit

SavingsAccount’s primary
key has a foreign key
constraint to Account

© 2014 Time2Master 12
Joined Tables in Action
Account Table SavingsAccount CheckingAccount

+ Normalized Schema
+ Database view is similar to domain view
– Inserting or updating an entity results in multiple
insert or update statements
– Necessary joins can give lower query performance

© 2014 Time2Master 13
Joined – No Discriminator Value
select
account0_.number as number0_,
account0_.balance as balance0_,
account0_.owner_id as owner3_0_,
account0_1_.overdraftLimit as overdraf1_1_,
account0_2_.APY as APY2_,
case
when account0_1_.number is not null then 1
when account0_2_.number is not null then 2
when account0_.number is not null then 0
end as clazz_
from
Account account0_
left outer join
CheckingAccount account0_1_
on account0_.number=account0_1_.number
left outer join
SavingsAccount account0_2_
on account0_.number=account0_2_.number
© 2014 Time2Master 14
Joined
Just specify the inheritance
strategy, nothing else
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Account { <<abstract>>
@Id Account
@GeneratedValue +number
private long number; +balance
private double balance;

...
SavingsAccount CheckingAccount
+APY +overdraftLimit

@Entity
public class SavingsAccount extends Account {
private double APY;

...
Subclasses can be mapped as normal
entity classes, but without identifiers
@Entity
public class CheckingAccount extends Account {
private double overdraftLimit;

...

© 2014 Time2Master 15
XML
<hibernate-mapping package="single">
<class name="Account" abstract="true"> Abstract account class
<id name="number">
<generator class="native" />
</id>

<property name="balance" />

<joined-subclass name="SavingsAccount"> Joined Subclasses are also


<key column="number" />
specified inside the super class
<property name="APY" />
</joined-subclass>

<joined-subclass name="CheckingAccount">
<key column="number" />
Need an additional <key> tag to specify
<property name="overdraftLimit" />
</joined-subclass> the PK / join column in the subclasses
</class>
</hibernate-mapping>

<<abstract>>
Account
+number
+balance

SavingsAccount CheckingAccount
+APY +overdraftLimit

© 2014 Time2Master 16
Inheritance Mapping

TABLE PER CONCRETE CLASS

© 2014 Time2Master 17
Table per Concrete Class
 Table per Concrete Class uses a table for each
concrete (non-abstract) class
 Subclass tables include all superclass properties
 Polymorphic queries use UNION operations
If the account class
was not abstract
<<abstract>> there would also be
Account
an account table
+number
+balance

SavingsAccount CheckingAccount
+APY +overdraftLimit

Savings account has Checking account also


number and balance has number and
columns balance columns

© 2014 Time2Master 18
Concrete Class in Action
SavingsAccount CheckingAccount

+ Very efficient non-polymorphic queries


+ Decently efficient polymorphic queries
– Cannot use Identity column ID generation
– Polymorphic one too many associations only
supported for bi-directional associations
– Subclass properties cannot use primitives
– JPA does not require its implementation (optional)

© 2014 Time2Master 19
Table Per Concrete – No Discriminator Value
select
account0_.number as number0_,
account0_.balance as balance0_,
account0_.owner_id as owner3_0_,
account0_.overdraftLimit as overdraf1_1_,
account0_.APY as APY2_,
account0_.clazz_ as clazz_
from
( select
number,
balance,
owner_id,
overdraftLimit,
cast(null as int) as APY,
1 as clazz_
from
CheckingAccount
union
all select
number,
balance,
owner_id,
cast(null as int) as overdraftLimit,
APY,
2 as clazz_
from
SavingsAccount
) account0_

© 2014 Time2Master 20
Table per Class
Just specify the inheritance
strategy, nothing else
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) <<abstract>>
Account
public class Account {
+number
@Id +balance
@GeneratedValue(strategy=GenerationType.TABLE)
private long number;
private double balance; Id generation can not
use identity column
... SavingsAccount CheckingAccount
+APY +overdraftLimit

Normal @Entity mapping


@Entity
public class SavingsAccount extends Account {
private Double APY;
Java.util.Double instead
... of primitive double type

@Entity
public class CheckingAccount extends Account {
private Double overdraftLimit;
Java.util.Double instead
...
of primitive double type

© 2014 Time2Master 21
XML
<hibernate-mapping package="concrete">
<class name="Account" abstract="true">
<id name="number">
<generator class="hilo" /> Identity generation can
</id> not use identity column
<property name="balance" />

<union-subclass name="SavingsAccount">
<property name="APY" /> <union-subclass> tag
</union-subclass>

<union-subclass name="CheckingAccount">
<property name="overdraftLimit" />
</union-subclass>
</class>
</hibernate-mapping>

<<abstract>>
Account
+number
+balance

SavingsAccount CheckingAccount
+APY +overdraftLimit

© 2014 Time2Master 22
Inheritance Mapping

WRAPPING UP

© 2014 Time2Master 23
Recommendations
 If subclasses don’t contain a lot of properties
use single table per hierarchy
 If subclasses have many properties it is
generally best to use joined tables
 Generally avoid using table per concrete class
unless you do not have any polymorphic
associations

© 2014 Time2Master 24
Active Learning
 What are the advantages and disadvantages
of the joined table strategy?

 Why should we not specify @Id on sub


classes?

© 2014 Time2Master 25
Module Summary
 In this module we covered the different ways
to map inheritance with Hibernate
 Single Table: De-normalized schema, but very
efficient queries
 Joined Tables: Normalized schema, but less
efficient queries
 Table per Concrete: has some issues, but is very
efficient if polymorphism is not a priority
 Which strategy to use depends on your
business needs, when in doubt the joined
table is the most flexible, although slower
© 2014 Time2Master 26

You might also like