Inheritance in Hibernate
Hibernate Supports 3 Types of Inheritance

In One Table per Concrete class scheme, each concrete class is mapped as normal persistent class. Thus we have 3 tables; PERSON, EMPLOYEE and OWNER to persist the class data. In this scheme, the mapping of the subclass repeats the properties of the parent class.
Following are the advantages and disadvantages of One Table per Subclass scheme.


File: Person.java
File: Employee.java
File: Owner.java
File: Person.hbm.xml
Note that we have defined only one hibernate mapping (hbm) file
We mapped all the classes using simple tag in hbm. This is the usual way of mapping classes in XML.
File: Person.java
File: Employee.java
File: Owner.java
Both Employee and Owner classes are child of Person class. Thus while specifying the mappings, we used
The AttributeOverride annotation may be applied to an entity that extends a mapped superclass or to an embedded field or property to override a basic mapping defined by the mapped superclass or embeddable class. If the AttributeOverride annotation is not specified, the column is mapped the same as in the original mapping.
Thus in over case, firstname and lastname are defined in parent class Person and mapped in child class Employee and Owner using @AttributeOverrides annotation.
This strategy supports one-to-many associations provided that they are bidirectional. This strategy does not support the IDENTITY generator strategy: the id has to be shared across several tables. Consequently, when using this strategy, you should not use AUTO nor IDENTITY. Note that in below Main class we specified the primary key explicitly.
The Main class is used to persist


In One Table per Subclass scheme, each class persist the data in its own separate table. Thus we have 3 tables; PERSON, EMPLOYEE and OWNER to persist the class data. Note that a foreign key relationship exists between the subclass tables and super class table. Thus the common data is stored in PERSON table and subclass specific fields are stored in EMPLOYEE and OWNER tables.
Following are the advantages and disadvantages of One Table per Subclass scheme.
File: Person.java
File: Employee.java
File: Owner.java
File: Person.hbm.xml
Note that we have defined only one hibernate mapping (hbm) file
tag is used to define the discriminator column.
tag is used to map the subclass Employee. Note that we have not used the usual
The discriminator-value for
File: Person.java
The
File: Employee.java
File: Owner.java
Both Employee and Owner classes are child of Person class. Thus while specifying the mappings, we used
It is used to join the primary table of an entity subclass in the JOINED mapping strategy to the primary table of its superclass; it is used within a SecondaryTable annotation to join a secondary table to a primary table; and it may be used in a OneToOne mapping in which the primary key of the referencing entity is used as a foreign key to the referenced entity.
If no PrimaryKeyJoinColumn annotation is specified for a subclass in the JOINED mapping strategy, the foreign key columns are assumed to have the same names as the primary key columns of the primary table of the superclass
The Main class is used to persist


In One Table per Concrete class scheme, each concrete class is mapped as normal persistent class. Thus we have 3 tables; PERSON, EMPLOYEE and OWNER to persist the class data. In this scheme, the mapping of the subclass repeats the properties of the parent class.
Following are the advantages and disadvantages of One Table per Subclass scheme.


File: Person.java
File: Employee.java
File: Owner.java
File: Person.hbm.xml
Note that we have defined only one hibernate mapping (hbm) file
We mapped all the classes using simple tag in hbm. This is the usual way of mapping classes in XML.
File: Person.java
File: Employee.java
File: Owner.java
Both Employee and Owner classes are child of Person class. Thus while specifying the mappings, we used
The AttributeOverride annotation may be applied to an entity that extends a mapped superclass or to an embedded field or property to override a basic mapping defined by the mapped superclass or embeddable class. If the AttributeOverride annotation is not specified, the column is mapped the same as in the original mapping.
Thus in over case, firstname and lastname are defined in parent class Person and mapped in child class Employee and Owner using @AttributeOverrides annotation.
This strategy supports one-to-many associations provided that they are bidirectional. This strategy does not support the IDENTITY generator strategy: the id has to be shared across several tables. Consequently, when using this strategy, you should not use AUTO nor IDENTITY. Note that in below Main class we specified the primary key explicitly.
The Main class is used to persist

Hibernate Supports 3 Types of Inheritance
- One Table Per Class Hierarchy (Annotation & XML mapping)
- One Table Per Subclass (Annotation & XML mapping)
- One Table Per Concrete Class (Annotation & XML mapping)
1) One Table per Concrete Class example
Suppose we have a class Person with subclasses Employee and Owner. Following the class diagram and relationship of these classes.In One Table per Concrete class scheme, each concrete class is mapped as normal persistent class. Thus we have 3 tables; PERSON, EMPLOYEE and OWNER to persist the class data. In this scheme, the mapping of the subclass repeats the properties of the parent class.
Following are the advantages and disadvantages of One Table per Subclass scheme.
Advantages
- This is the easiest method of Inheritance mapping to implement.
Disadvantages
- Data thats belongs to a parent class is scattered across a number of subclass tables, which represents concrete classes.
- This hierarchy is not recommended for most cases.
- Changes to a parent class is reflected to large number of tables
- A query couched in terms of parent class is likely to cause a large number of select operations
Create Database Table to persist Concrete classes
CREATE TABLE `person` ( `person_id` BIGINT (20) NOT NULL AUTO_INCREMENT, `firstname` VARCHAR (50) NOT NULL DEFAULT '0' , `lastname` VARCHAR (50) NOT NULL DEFAULT '0' , PRIMARY KEY (`person_id`) ) CREATE TABLE `employee` ( `person_id` BIGINT (10) NOT NULL AUTO_INCREMENT, `firstname` VARCHAR (50) NOT NULL , `lastname` VARCHAR (50) NOT NULL , `joining_date` DATE NULL DEFAULT NULL , `department_name` VARCHAR (50) NULL DEFAULT NULL , PRIMARY KEY (`person_id`) ) CREATE TABLE `owner` ( `person_id` BIGINT (20) NOT NULL AUTO_INCREMENT, `firstname` VARCHAR (50) NOT NULL DEFAULT '0' , `lastname` VARCHAR (50) NOT NULL DEFAULT '0' , `stocks` BIGINT (11) NULL DEFAULT NULL , `partnership_stake` BIGINT (11) NULL DEFAULT NULL , PRIMARY KEY (`person_id`) ) |
Project Structure in Eclipse
For XML mapping
For Annotation mapping
Hibernate Inheritance: XML Mapping
Following is the example where we map Person, Employee and Owner entity classes using XML mapping.File: Person.java
package net.viralpatel.hibernate; public class Person { private Long personId; private String firstname; private String lastname; // Constructors and Getter/Setter methods, } |
package net.viralpatel.hibernate; import java.util.Date; public class Employee extends Person { private Date joiningDate; private String departmentName; // Constructors and Getter/Setter methods, } |
package net.viralpatel.hibernate; public class Owner extends Person { private Long stocks; private Long partnershipStake; // Constructors and Getter/Setter methods, } |
<!--?xml version="1.0" encoding="UTF-8"?--> < hibernate-mapping package = "net.viralpatel.hibernate" > < class name = "Person" table = "PERSON" > < id name = "personId" column = "PERSON_ID" > < generator class = "native" > </ generator ></ id > < property name = "firstname" > < property name = "lastname" column = "lastname" > </ property ></ property ></ class > < class name = "Employee" > < id name = "personId" column = "PERSON_ID" > < generator class = "native" > </ generator ></ id > < property name = "firstname" > < property name = "lastname" column = "lastname" > < property name = "departmentName" column = "department_name" > < property name = "joiningDate" type = "date" column = "joining_date" > </ property ></ property ></ property ></ property ></ class > < class name = "Owner" > < id name = "personId" column = "PERSON_ID" > < generator class = "native" > </ generator ></ id > < property name = "firstname" > < property name = "lastname" column = "lastname" > < property name = "stocks" column = "stocks" > < property name = "partnershipStake" column = "partnership_stake" > </ property ></ property ></ property ></ property ></ class > </ hibernate-mapping > |
Note that we have defined only one hibernate mapping (hbm) file
Person.hbm.xml
. Both Person
and Employee
model class are defined within one hbm file. We mapped all the classes using simple tag in hbm. This is the usual way of mapping classes in XML.
Hibernate Inheritance: Annotation Mapping
Following is the example where we map Person, Employee and Owner entity classes using JPA Annotations.File: Person.java
package net.viralpatel.hibernate; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.Table; @Entity @Table (name = "PERSON" ) @Inheritance (strategy = InheritanceType.TABLE_PER_CLASS) public class Person { @Id @Column (name = "PERSON_ID" ) private Long personId; @Column (name = "FIRSTNAME" ) private String firstname; @Column (name = "LASTNAME" ) private String lastname; public Person() { } public Person(String firstname, String lastname) { this .firstname = firstname; this .lastname = lastname; } // Getter and Setter methods, } |
@Inheritance
– Defines the inheritance
strategy to be used for an entity class hierarchy. It is specified on
the entity class that is the root of the entity class hierarchy. @InheritanceType
– Defines inheritance strategy options. TABLE_PER_CLASS is a strategy to map table per concrete class.File: Employee.java
package net.viralpatel.hibernate; import java.util.Date; import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; @Entity @Table (name= "EMPLOYEE" ) @AttributeOverrides ({ @AttributeOverride (name= "firstname" , column= @Column (name= "FIRSTNAME" )), @AttributeOverride (name= "lastname" , column= @Column (name= "LASTNAME" )) }) public class Employee extends Person { @Column (name= "joining_date" ) private Date joiningDate; @Column (name= "department_name" ) private String departmentName; public Employee() { } public Employee(String firstname, String lastname, String departmentName, Date joiningDate) { super (firstname, lastname); this .departmentName = departmentName; this .joiningDate = joiningDate; } // Getter and Setter methods, } |
package net.viralpatel.hibernate; import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; @Entity @Table (name= "OWNER" ) @AttributeOverrides ({ @AttributeOverride (name= "firstname" , column= @Column (name= "FIRSTNAME" )), @AttributeOverride (name= "lastname" , column= @Column (name= "LASTNAME" )) }) public class Owner extends Person { @Column (name= "stocks" ) private Long stocks; @Column (name= "partnership_stake" ) private Long partnershipStake; public Owner() { } public Owner(String firstname, String lastname, Long stocks, Long partnershipStake) { super (firstname, lastname); this .stocks = stocks; this .partnershipStake = partnershipStake; } // Getter and Setter methods, } |
Both Employee and Owner classes are child of Person class. Thus while specifying the mappings, we used
@AttributeOverrides
to map them.@AttributeOverrides
– This annotation is used to override mappings of multiple properties or fields.@AttributeOverride
– The
AttributeOverride annotation is used to override the mapping of a Basic
(whether explicit or default) property or field or Id property or field.The AttributeOverride annotation may be applied to an entity that extends a mapped superclass or to an embedded field or property to override a basic mapping defined by the mapped superclass or embeddable class. If the AttributeOverride annotation is not specified, the column is mapped the same as in the original mapping.
Thus in over case, firstname and lastname are defined in parent class Person and mapped in child class Employee and Owner using @AttributeOverrides annotation.
This strategy supports one-to-many associations provided that they are bidirectional. This strategy does not support the IDENTITY generator strategy: the id has to be shared across several tables. Consequently, when using this strategy, you should not use AUTO nor IDENTITY. Note that in below Main class we specified the primary key explicitly.
Main class
package net.viralpatel.hibernate; import java.util.Date; import org.hibernate.Session; import org.hibernate.SessionFactory; public class Main { public static void main(String[] args) { SessionFactory sf = HibernateUtil.getSessionFactory(); Session session = sf.openSession(); session.beginTransaction(); Person person = new Person( "Steve" , "Balmer" ); person.setPersonId(1L); session.save(person); Employee employee = new Employee( "James" , "Gosling" , "Marketing" , new Date()); employee.setPersonId(2L); session.save(employee); Owner owner = new Owner( "Bill" , "Gates" , 300L, 20L); owner.setPersonId(3L); session.save(owner); session.getTransaction().commit(); session.close(); } } |
Person
, Employee
and Owner
object instances. Note that these classes are persisted in different
tables and parent attributes (firstname, lastname) are repeated across
all tables. Output
Hibernate: insert into PERSON (FIRSTNAME, LASTNAME, PERSON_ID) values (?, ?, ?) Hibernate: insert into EMPLOYEE (FIRSTNAME, LASTNAME, department_name, joining_date, PERSON_ID) values (?, ?, ?, ?, ?) Hibernate: insert into OWNER (FIRSTNAME, LASTNAME, partnership_stake, stocks, PERSON_ID) values (?, ?, ?, ?, ?) |
2) One Table Per Subclass example
Suppose we have a class Person with subclass Employee and Owner. Following the class diagram and relationship of these classes.In One Table per Subclass scheme, each class persist the data in its own separate table. Thus we have 3 tables; PERSON, EMPLOYEE and OWNER to persist the class data. Note that a foreign key relationship exists between the subclass tables and super class table. Thus the common data is stored in PERSON table and subclass specific fields are stored in EMPLOYEE and OWNER tables.
Following are the advantages and disadvantages of One Table per Subclass scheme.
Advantage
- Using this hierarchy, does not require complex changes to the database schema when a single parent class is modified.
- It works well with shallow hierarchy.
Disadvantage
- As the hierarchy grows, it may result in poor performance.
- The number of joins required to construct a subclass also grows.
Create Database Table to persist Subclass
CREATE TABLE `person` ( `person_id` BIGINT (20) NOT NULL AUTO_INCREMENT, `firstname` VARCHAR (50) NOT NULL DEFAULT '0' , `lastname` VARCHAR (50) NOT NULL DEFAULT '0' , PRIMARY KEY (`person_id`) ) CREATE TABLE `employee` ( `person_id` BIGINT (10) NOT NULL , `joining_date` DATE NULL DEFAULT NULL , `department_name` VARCHAR (50) NULL DEFAULT NULL , PRIMARY KEY (`person_id`), CONSTRAINT `FK_PERSON` FOREIGN KEY (`person_id`) REFERENCES `person` (`person_id`) ) CREATE TABLE `owner` ( `person_id` BIGINT (20) NOT NULL DEFAULT '0' , `stocks` BIGINT (11) NULL DEFAULT NULL , `partnership_stake` BIGINT (11) NULL DEFAULT NULL , PRIMARY KEY (`person_id`), CONSTRAINT `FK_PERSON2` FOREIGN KEY (`person_id`) REFERENCES `person` (`person_id`) ) |
Hibernate Inheritance: XML Mapping
Following is the example where we map Person, Employee and Owner entity classes using XML mapping.File: Person.java
package net.viralpatel.hibernate; public class Person { private Long personId; private String firstname; private String lastname; // Constructors and Getter/Setter methods, } |
package net.viralpatel.hibernate; import java.util.Date; public class Employee extends Person { private Date joiningDate; private String departmentName; // Constructors and Getter/Setter methods, } |
package net.viralpatel.hibernate; public class Owner extends Person { private Long stocks; private Long partnershipStake; // Constructors and Getter/Setter methods, } |
<!--?xml version= "1.0" encoding= "UTF-8" ?--> <hibernate-mapping package = "net.viralpatel.hibernate" > < class name= "Person" table= "PERSON" > <id name= "personId" column= "PERSON_ID" > <generator class = "native" > </generator></id> <property name= "firstname" > <property name= "lastname" column= "lastname" > <joined-subclass name= "Employee" extends = "Person" > <key column= "person_id" > <property name= "departmentName" column= "department_name" > <property name= "joiningDate" type= "date" column= "joining_date" > </property></property></key></joined-subclass> <joined-subclass name= "Owner" extends = "Person" > <key column= "person_id" > <property name= "stocks" column= "stocks" > <property name= "partnershipStake" column= "partnership_stake" > </property></property></key></joined-subclass> </property></property></ class > </hibernate-mapping> |
Note that we have defined only one hibernate mapping (hbm) file
Person.hbm.xml
. Both Person
and Employee
model class are defined within one hbm file. tag is used to define the discriminator column.
tag is used to map the subclass Employee. Note that we have not used the usual
tag to map Employee as it falls below in the hierarchy tree.The discriminator-value for
Person
is defined as “P” and that for Employee
is defined “E”, Thus, when Hibernate will persist the data for person or employee it will accordingly populate this value.Hibernate Inheritance: Annotation Mapping
Following is the example where we map Employee and Person entity classes using JPA Annotations.File: Person.java
package net.viralpatel.hibernate; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.Table; @Entity @Table (name = "PERSON" ) @Inheritance (strategy=InheritanceType.JOINED) public class Person { @Id @GeneratedValue @Column (name = "PERSON_ID" ) private Long personId; @Column (name = "FIRSTNAME" ) private String firstname; @Column (name = "LASTNAME" ) private String lastname; public Person() { } public Person(String firstname, String lastname) { this .firstname = firstname; this .lastname = lastname; } // Getter and Setter methods, } |
The
Person
class is the root of hierarchy. Hence we have used some annotations to make it as the root.@Inheritance
– Defines the inheritance
strategy to be used for an entity class hierarchy. It is specified on
the entity class that is the root of the entity class hierarchy. @InheritanceType
– Defines inheritance
strategy options. JOINED is a strategy in which fields that are specific
to a subclass are mapped to a separate table than the fields that are
common to the parent class, and a join is performed to instantiate the
subclass. Thus fields of Employee (joining_date, department) and Owner
(stocks etc) are mapped to their respective tables.File: Employee.java
package net.viralpatel.hibernate; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; @Entity @Table (name= "EMPLOYEE" ) @PrimaryKeyJoinColumn (name= "PERSON_ID" ) public class Employee extends Person { @Column (name= "joining_date" ) private Date joiningDate; @Column (name= "department_name" ) private String departmentName; public Employee() { } public Employee(String firstname, String lastname, String departmentName, Date joiningDate) { super (firstname, lastname); this .departmentName = departmentName; this .joiningDate = joiningDate; } // Getter and Setter methods, } |
package net.viralpatel.hibernate; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; @Entity @Table (name= "OWNER" ) @PrimaryKeyJoinColumn (name= "PERSON_ID" ) public class Owner extends Person { @Column (name= "stocks" ) private Long stocks; @Column (name= "partnership_stake" ) private Long partnershipStake; public Owner() { } public Owner(String firstname, String lastname, Long stocks, Long partnershipStake) { super (firstname, lastname); this .stocks = stocks; this .partnershipStake = partnershipStake; } // Getter and Setter methods, } |
Both Employee and Owner classes are child of Person class. Thus while specifying the mappings, we used
@PrimaryKeyJoinColumn
to map it to parent table.@PrimaryKeyJoinColumn
– This annotation specifies a primary key column that is used as a foreign key to join to another table. It is used to join the primary table of an entity subclass in the JOINED mapping strategy to the primary table of its superclass; it is used within a SecondaryTable annotation to join a secondary table to a primary table; and it may be used in a OneToOne mapping in which the primary key of the referencing entity is used as a foreign key to the referenced entity.
If no PrimaryKeyJoinColumn annotation is specified for a subclass in the JOINED mapping strategy, the foreign key columns are assumed to have the same names as the primary key columns of the primary table of the superclass
Main class
package net.viralpatel.hibernate; import java.util.Date; import org.hibernate.Session; import org.hibernate.SessionFactory; public class Main { public static void main(String[] args) { SessionFactory sf = HibernateUtil.getSessionFactory(); Session session = sf.openSession(); session.beginTransaction(); Person person = new Person( "Steve" , "Balmer" ); session.save(person); Employee employee = new Employee( "James" , "Gosling" , "Marketing" , new Date()); session.save(employee); Owner owner = new Owner( "Bill" , "Gates" , 300L, 20L); session.save(owner); session.getTransaction().commit(); session.close(); } } |
Person
, Employee
and Owner
object instances. Note that these classes are persisted in different tables. Output
Hibernate: insert into PERSON (firstname, lastname) values (?, ?) Hibernate: insert into PERSON (firstname, lastname) values (?, ?) Hibernate: insert into Employee (department_name, joining_date, person_id) values (?, ?, ?) Hibernate: insert into PERSON (firstname, lastname) values (?, ?) Hibernate: insert into Owner (stocks, partnership_stake, person_id) values (?, ?, ?) |
3) One Table per Concrete Class example
Suppose we have a class Person with subclasses Employee and Owner. Following the class diagram and relationship of these classes.In One Table per Concrete class scheme, each concrete class is mapped as normal persistent class. Thus we have 3 tables; PERSON, EMPLOYEE and OWNER to persist the class data. In this scheme, the mapping of the subclass repeats the properties of the parent class.
Following are the advantages and disadvantages of One Table per Subclass scheme.
Advantages
- This is the easiest method of Inheritance mapping to implement.
Disadvantages
- Data thats belongs to a parent class is scattered across a number of subclass tables, which represents concrete classes.
- This hierarchy is not recommended for most cases.
- Changes to a parent class is reflected to large number of tables
- A query couched in terms of parent class is likely to cause a large number of select operations
Create Database Table to persist Concrete classes
CREATE TABLE `person` ( `person_id` BIGINT (20) NOT NULL AUTO_INCREMENT, `firstname` VARCHAR (50) NOT NULL DEFAULT '0' , `lastname` VARCHAR (50) NOT NULL DEFAULT '0' , PRIMARY KEY (`person_id`) ) CREATE TABLE `employee` ( `person_id` BIGINT (10) NOT NULL AUTO_INCREMENT, `firstname` VARCHAR (50) NOT NULL , `lastname` VARCHAR (50) NOT NULL , `joining_date` DATE NULL DEFAULT NULL , `department_name` VARCHAR (50) NULL DEFAULT NULL , PRIMARY KEY (`person_id`) ) CREATE TABLE `owner` ( `person_id` BIGINT (20) NOT NULL AUTO_INCREMENT, `firstname` VARCHAR (50) NOT NULL DEFAULT '0' , `lastname` VARCHAR (50) NOT NULL DEFAULT '0' , `stocks` BIGINT (11) NULL DEFAULT NULL , `partnership_stake` BIGINT (11) NULL DEFAULT NULL , PRIMARY KEY (`person_id`) ) |
Project Structure in Eclipse
For XML mapping
For Annotation mapping
Hibernate Inheritance: XML Mapping
Following is the example where we map Person, Employee and Owner entity classes using XML mapping.File: Person.java
package net.viralpatel.hibernate; public class Person { private Long personId; private String firstname; private String lastname; // Constructors and Getter/Setter methods, } |
package net.viralpatel.hibernate; import java.util.Date; public class Employee extends Person { private Date joiningDate; private String departmentName; // Constructors and Getter/Setter methods, } |
package net.viralpatel.hibernate; public class Owner extends Person { private Long stocks; private Long partnershipStake; // Constructors and Getter/Setter methods, } |
<!--?xml version="1.0" encoding="UTF-8"?--> < hibernate-mapping package = "net.viralpatel.hibernate" > < class name = "Person" table = "PERSON" > < id name = "personId" column = "PERSON_ID" > < generator class = "native" > </ generator ></ id > < property name = "firstname" > < property name = "lastname" column = "lastname" > </ property ></ property ></ class > < class name = "Employee" > < id name = "personId" column = "PERSON_ID" > < generator class = "native" > </ generator ></ id > < property name = "firstname" > < property name = "lastname" column = "lastname" > < property name = "departmentName" column = "department_name" > < property name = "joiningDate" type = "date" column = "joining_date" > </ property ></ property ></ property ></ property ></ class > < class name = "Owner" > < id name = "personId" column = "PERSON_ID" > < generator class = "native" > </ generator ></ id > < property name = "firstname" > < property name = "lastname" column = "lastname" > < property name = "stocks" column = "stocks" > < property name = "partnershipStake" column = "partnership_stake" > </ property ></ property ></ property ></ property ></ class > </ hibernate-mapping > |
Note that we have defined only one hibernate mapping (hbm) file
Person.hbm.xml
. Both Person
and Employee
model class are defined within one hbm file. We mapped all the classes using simple tag in hbm. This is the usual way of mapping classes in XML.
Hibernate Inheritance: Annotation Mapping
Following is the example where we map Person, Employee and Owner entity classes using JPA Annotations.File: Person.java
package net.viralpatel.hibernate; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.Table; @Entity @Table (name = "PERSON" ) @Inheritance (strategy = InheritanceType.TABLE_PER_CLASS) public class Person { @Id @Column (name = "PERSON_ID" ) private Long personId; @Column (name = "FIRSTNAME" ) private String firstname; @Column (name = "LASTNAME" ) private String lastname; public Person() { } public Person(String firstname, String lastname) { this .firstname = firstname; this .lastname = lastname; } // Getter and Setter methods, } |
@Inheritance
– Defines the inheritance
strategy to be used for an entity class hierarchy. It is specified on
the entity class that is the root of the entity class hierarchy. @InheritanceType
– Defines inheritance strategy options. TABLE_PER_CLASS is a strategy to map table per concrete class.File: Employee.java
package net.viralpatel.hibernate; import java.util.Date; import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; @Entity @Table (name= "EMPLOYEE" ) @AttributeOverrides ({ @AttributeOverride (name= "firstname" , column= @Column (name= "FIRSTNAME" )), @AttributeOverride (name= "lastname" , column= @Column (name= "LASTNAME" )) }) public class Employee extends Person { @Column (name= "joining_date" ) private Date joiningDate; @Column (name= "department_name" ) private String departmentName; public Employee() { } public Employee(String firstname, String lastname, String departmentName, Date joiningDate) { super (firstname, lastname); this .departmentName = departmentName; this .joiningDate = joiningDate; } // Getter and Setter methods, } |
package net.viralpatel.hibernate; import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; @Entity @Table (name= "OWNER" ) @AttributeOverrides ({ @AttributeOverride (name= "firstname" , column= @Column (name= "FIRSTNAME" )), @AttributeOverride (name= "lastname" , column= @Column (name= "LASTNAME" )) }) public class Owner extends Person { @Column (name= "stocks" ) private Long stocks; @Column (name= "partnership_stake" ) private Long partnershipStake; public Owner() { } public Owner(String firstname, String lastname, Long stocks, Long partnershipStake) { super (firstname, lastname); this .stocks = stocks; this .partnershipStake = partnershipStake; } // Getter and Setter methods, } |
Both Employee and Owner classes are child of Person class. Thus while specifying the mappings, we used
@AttributeOverrides
to map them.@AttributeOverrides
– This annotation is used to override mappings of multiple properties or fields.@AttributeOverride
– The
AttributeOverride annotation is used to override the mapping of a Basic
(whether explicit or default) property or field or Id property or field.The AttributeOverride annotation may be applied to an entity that extends a mapped superclass or to an embedded field or property to override a basic mapping defined by the mapped superclass or embeddable class. If the AttributeOverride annotation is not specified, the column is mapped the same as in the original mapping.
Thus in over case, firstname and lastname are defined in parent class Person and mapped in child class Employee and Owner using @AttributeOverrides annotation.
This strategy supports one-to-many associations provided that they are bidirectional. This strategy does not support the IDENTITY generator strategy: the id has to be shared across several tables. Consequently, when using this strategy, you should not use AUTO nor IDENTITY. Note that in below Main class we specified the primary key explicitly.
Main class
package net.viralpatel.hibernate; import java.util.Date; import org.hibernate.Session; import org.hibernate.SessionFactory; public class Main { public static void main(String[] args) { SessionFactory sf = HibernateUtil.getSessionFactory(); Session session = sf.openSession(); session.beginTransaction(); Person person = new Person( "Steve" , "Balmer" ); person.setPersonId(1L); session.save(person); Employee employee = new Employee( "James" , "Gosling" , "Marketing" , new Date()); employee.setPersonId(2L); session.save(employee); Owner owner = new Owner( "Bill" , "Gates" , 300L, 20L); owner.setPersonId(3L); session.save(owner); session.getTransaction().commit(); session.close(); } } |
Person
, Employee
and Owner
object instances. Note that these classes are persisted in different
tables and parent attributes (firstname, lastname) are repeated across
all tables. Output
Hibernate: insert into PERSON (FIRSTNAME, LASTNAME, PERSON_ID) values (?, ?, ?) Hibernate: insert into EMPLOYEE (FIRSTNAME, LASTNAME, department_name, joining_date, PERSON_ID) values (?, ?, ?, ?, ?) Hibernate: insert into OWNER (FIRSTNAME, LASTNAME, partnership_stake, stocks, PERSON_ID) values (?, ?, ?, ?, ?) |