Hibernate Tutorial

Core Hibernate

Hibernate Mapping

Hibernate Annotations

Hibernate with Spring Framework

Hibernate with Database

Hibernate Log4j

Inheritance Mapping

Hibernate - Table Per Concrete Class using XML File

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.

1. Setting Up:

Ensure you have a Hibernate project ready with the necessary dependencies and configuration files.

2. Define the Entity Classes:

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...
}

3. XML Mapping:

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).

4. Persistence:

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.

5. Fetching:

Fetching is straightforward. When you fetch a Cat entity, Hibernate will retrieve it from the Cat table.

Cat retrievedCat = session.get(Cat.class, catId);

6. Benefits & Drawbacks:

Benefits:

  • The schema is normalized.
  • No need for nullable columns in child tables, as each table only contains columns for the attributes declared in that class.

Drawbacks:

  • Polymorphic queries can be less efficient, as they may require unions across multiple tables.
  • Inserting a subclass entity requires an insert statement for the table corresponding to that subclass.

Conclusion:

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.

  1. Hibernate table per concrete class XML mapping example:

    • Table per concrete class XML mapping in Hibernate involves configuring each concrete class with its own mapping file.
    • Define separate XML mapping files for each concrete class.
    <!-- 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>
    
  2. Configuring table per concrete class inheritance in Hibernate using XML:

    • Configure table per concrete class inheritance in Hibernate XML by using <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>
    
  3. Mapping concrete classes with Hibernate XML mapping:

    • Map concrete classes in Hibernate XML mapping using <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>
    
  4. Table per concrete class vs table per hierarchy in Hibernate XML:

    • In Hibernate XML, table per concrete class involves using <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>
    
  5. Inheritance strategies with XML mapping in Hibernate:

    • In Hibernate XML mapping, inheritance strategies are defined using <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>
    
  6. Hibernate XML mapping for @Inheritance annotation in table per concrete class:

    • The <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>
    
  7. Handling associations in table per concrete class mapping with XML:

    • Handle associations in table per concrete class mapping with XML by defining relationships in the XML mapping files.
    <!-- 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>
    
  8. HQL queries for table per concrete class inheritance in Hibernate XML:

    • Use HQL (Hibernate Query Language) for queries specific to the table per concrete class strategy 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.