Hibernate Tutorial
Core Hibernate
Hibernate Mapping
Hibernate Annotations
Hibernate with Spring Framework
Hibernate with Database
Hibernate Log4j
Inheritance Mapping
Mapping inheritance in Hibernate using the "Table Per Concrete Class" strategy with XML configuration requires each concrete subclass to have its table that includes columns for all inherited attributes. This tutorial will guide you on how to map this strategy using XML files.
Ensure you have a Hibernate project ready with the necessary dependencies and configuration files.
Base Class (Animal):
This class is a simple POJO with an id
and name
attribute.
public class Animal { private Long id; private String name; // Getters, setters, constructors... }
Concrete Subclasses (Cat and Dog):
public class Cat extends Animal { private String purringVolume; // Getters, setters, constructors... } public class Dog extends Animal { private String barkPitch; // Getters, setters, constructors... }
Create XML mapping files for each class:
Animal.hbm.xml:
<hibernate-mapping> <class name="Animal" table="ANIMAL" abstract="true"> <id name="id" column="ID"> <generator class="native"/> </id> <property name="name" column="NAME"/> </class> </hibernate-mapping>
Note that the abstract
attribute is set to "true" because we will not have an actual table for Animal
.
Cat.hbm.xml:
<hibernate-mapping> <class name="Cat" table="CAT" extends="Animal"> <property name="purringVolume" column="PURRING_VOLUME"/> </class> </hibernate-mapping>
Dog.hbm.xml:
<hibernate-mapping> <class name="Dog" table="DOG" extends="Animal"> <property name="barkPitch" column="BARK_PITCH"/> </class> </hibernate-mapping>
Ensure that these XML files are appropriately registered in your Hibernate configuration file (hibernate.cfg.xml
).
When you persist an instance of Cat
:
Cat cat = new Cat(); cat.setName("Whiskers"); cat.setPurringVolume("Soft"); session.save(cat);
Hibernate will create a new row in the Cat
table with all the attributes of Cat
, including those inherited from Animal
.
Fetching is straightforward. When you fetch a Cat
entity, Hibernate will retrieve it from the Cat
table.
Cat retrievedCat = session.get(Cat.class, catId);
Benefits:
Drawbacks:
Using the "Table Per Concrete Class" strategy with XML configuration in Hibernate offers a flexible way of mapping inheritance. However, always evaluate if this strategy fits your application needs compared to the other available strategies.
Hibernate table per concrete class XML mapping example:
<!-- Animal.hbm.xml --> <class name="com.example.Animal" table="animal"> <id name="id" type="long"> <generator class="increment"/> </id> <!-- Common fields and mappings --> </class>
<!-- Cat.hbm.xml --> <class name="com.example.Cat" table="cat"> <joined-subclass extends="com.example.Animal"> <key column="animal_id"/> <!-- Cat-specific fields and mappings --> </joined-subclass> </class>
<!-- Dog.hbm.xml --> <class name="com.example.Dog" table="dog"> <joined-subclass extends="com.example.Animal"> <key column="animal_id"/> <!-- Dog-specific fields and mappings --> </joined-subclass> </class>
Configuring table per concrete class inheritance in Hibernate using XML:
<joined-subclass>
elements for each concrete class.<!-- Animal.hbm.xml --> <class name="com.example.Animal" table="animal"> <!-- Common fields and mappings --> </class>
<!-- Cat.hbm.xml --> <class name="com.example.Cat" table="cat"> <joined-subclass extends="com.example.Animal"> <key column="animal_id"/> <!-- Cat-specific fields and mappings --> </joined-subclass> </class>
<!-- Dog.hbm.xml --> <class name="com.example.Dog" table="dog"> <joined-subclass extends="com.example.Animal"> <key column="animal_id"/> <!-- Dog-specific fields and mappings --> </joined-subclass> </class>
Mapping concrete classes with Hibernate XML mapping:
<class>
elements for each concrete class and <joined-subclass>
for inheritance.<!-- Animal.hbm.xml --> <class name="com.example.Animal" table="animal"> <!-- Common fields and mappings --> </class>
<!-- Cat.hbm.xml --> <class name="com.example.Cat" table="cat"> <joined-subclass extends="com.example.Animal"> <key column="animal_id"/> <!-- Cat-specific fields and mappings --> </joined-subclass> </class>
<!-- Dog.hbm.xml --> <class name="com.example.Dog" table="dog"> <joined-subclass extends="com.example.Animal"> <key column="animal_id"/> <!-- Dog-specific fields and mappings --> </joined-subclass> </class>
Table per concrete class vs table per hierarchy in Hibernate XML:
<joined-subclass>
elements for each concrete class, while table per hierarchy uses <subclass>
elements.<!-- Animal.hbm.xml --> <class name="com.example.Animal" table="animal"> <!-- Common fields and mappings --> </class>
<!-- Cat.hbm.xml --> <subclass extends="com.example.Animal" discriminator-value="Cat"> <!-- Cat-specific fields and mappings --> </subclass>
<!-- Dog.hbm.xml --> <subclass extends="com.example.Animal" discriminator-value="Dog"> <!-- Dog-specific fields and mappings --> </subclass>
Inheritance strategies with XML mapping in Hibernate:
<joined-subclass>
, <subclass>
, or <union-subclass>
elements.<!-- Animal.hbm.xml --> <class name="com.example.Animal" table="animal"> <!-- Common fields and mappings --> </class>
<!-- Cat.hbm.xml --> <joined-subclass extends="com.example.Animal" table="cat"> <!-- Cat-specific fields and mappings --> </joined-subclass>
<!-- Dog.hbm.xml --> <joined-subclass extends="com.example.Animal" table="dog"> <!-- Dog-specific fields and mappings --> </joined-subclass>
Hibernate XML mapping for @Inheritance annotation in table per concrete class:
<joined-subclass>
element in Hibernate XML corresponds to the @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
annotation in table per concrete class.<!-- Animal.hbm.xml --> <class name="com.example.Animal" table="animal"> <!-- Common fields and mappings --> </class>
<!-- Cat.hbm.xml --> <joined-subclass extends="com.example.Animal" table="cat"> <!-- Cat-specific fields and mappings --> </joined-subclass>
<!-- Dog.hbm.xml --> <joined-subclass extends="com.example.Animal" table="dog"> <!-- Dog-specific fields and mappings --> </joined-subclass>
Handling associations in table per concrete class mapping with XML:
<!-- Animal.hbm.xml --> <class name="com.example.Animal" table="animal"> <!-- Common fields and mappings --> </class>
<!-- Cage.hbm.xml --> <class name="com.example.Cage" table="cage"> <set name="animals" table="animal" inverse="true" cascade="all"> <key column="cage_id"/> <one-to-many class="com.example.Animal"/> </set> </class>
HQL queries for table per concrete class inheritance in Hibernate XML:
String hql = "FROM Cat c WHERE c.color = :color"; Query query = session.createQuery(hql); query.setParameter("color", "black"); List<Cat> blackCats = query.list();
Replace this code with the relevant XML configuration.