Table per Class Strategy in Hibernate Inheritance

By | 2018-03-13T03:24:16+05:30 October 23rd, 2015|Hibernate|

Table per Class is one of the Hibernate inheritance strategy. As we discussed in the previous tutorial Types of Inheritance Mapping Strategies in Hibernate.
In this tutorials, we are going to implement the Table per Class strategy in Hibernate using xml configuration. We can also implement the same example using hibernate annotations here is the example.

Hibernate Table per Class Strategy :

We can use the Table per Class strategy, if we want to store the data of all classes hierarchy into a single database table. For this strategy we can store all classes data in a single table.

Since all classes data in hierarchy would be saved in a single database table, to identify a particular class data, hibernate needs an extra column called discriminator. By using this discriminator column, we can easily find a particular class data in table.

So then, while creating the table in database, apart from all the required columns, we need to create an extra column which is discriminator.

Database Table :


CREATE TABLE `payment` (
    `payid` INT(11) NOT NULL,
    `amount` DOUBLE NULL DEFAULT NULL,
    `cardnumber` INT(11) NULL DEFAULT NULL,
    `cardtype` VARCHAR(50) NULL DEFAULT NULL,
    `chqnumber` INT(11) NULL DEFAULT NULL,
    `chqtype` VARCHAR(50) NULL DEFAULT NULL,
    `paydate` DATE NULL DEFAULT NULL,
    `paymode` VARCHAR(50) NULL DEFAULT NULL COMMENT 'Discriminator column'
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB;

In hbm.xml file we need to configure the Table per Class strategy. Each subclass of inheritance is mapped by using <subclass> tag. The discriminator is configured by using the <discriminator> tag. The only restriction with <discriminator> tag is, it should be added immediately after closing the <id> tag.

Example for Hibernate Table per Class :

Table per ClassPayment.java

package com.onlinetutorialspoint.hibernate.model;

import java.util.Date;

public class Payment {

    private int paymentId;
    private double amount;
    private Date paymentDate;

    public int getPaymentId() {
        return paymentId;
    }

    public void setPaymentId(int paymentId) {
        this.paymentId = paymentId;
    }

    public double getAmount() {
        return amount;
    }

    public void setAmount(double amount) {
        this.amount = amount;
    }

    public Date getPaymentDate() {
        return paymentDate;
    }

    public void setPaymentDate(Date paymentDate) {
        this.paymentDate = paymentDate;
    }

}

Card.java

package com.onlinetutorialspoint.hibernate.model;

public class Card extends Payment {

    private int cardNumber;
    private String cardType;

    public int getCardNumber() {
        return cardNumber;
    }

    public void setCardNumber(int cardNumber) {
        this.cardNumber = cardNumber;
    }

    public String getCardType() {
        return cardType;
    }

    public void setCardType(String cardType) {
        this.cardType = cardType;
    }

}

Cheque.java

package com.onlinetutorialspoint.hibernate.model;

public class Cheque extends Payment {

    private int chequeNumber;
    private String chequeType;

    public int getChequeNumber() {
        return chequeNumber;
    }

    public void setChequeNumber(int chequeNumber) {
        this.chequeNumber = chequeNumber;
    }

    public String getChequeType() {
        return chequeType;
    }

    public void setChequeType(String chequeType) {
        this.chequeType = chequeType;
    }

}

Payment.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.onlinetutorialspoint.hibernate.model.Payment" table="payment">
        <id name="paymentId" column="payid"/>
        <discriminator column="paymode" type="string"/>
        <property name="amount"/>
        <property name="paymentDate" column="paydate" type="date"/>
        <subclass name="com.onlinetutorialspoint.hibernate.model.Card" discriminator-value="cp">
            <property name="cardNumber" column="cardnumber"/>
            <property name="cardType" column="cardtype"/>
        </subclass>
        <subclass name="com.onlinetutorialspoint.hibernate.model.Cheque" discriminator-value="chp">
            <property name="chequeNumber" column="chqnumber"/>
            <property name="chequeType" column="chqtype"/>
        </subclass>
    </class>
</hibernate-mapping>

hibernate.cfg.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/onlinetutorialspoint?zeroDateTimeBehavior=convertToNull</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">123456</property>
    <mapping resource="payment.hbm.xml"/>
  </session-factory>
</hibernate-configuration>

PaymentDAO.java

package com.onlinetutorialspoint.hibernate.dao;

import com.onlinetutorialspoint.hibernate.model.Card;
import com.onlinetutorialspoint.hibernate.model.Cheque;

public interface PaymentDAO {

    public void saveCard(Card card);

    public void saveCheque(Cheque cheque);
}

PaymentDAOImpl.java

package com.onlinetutorialspoint.hibernate.dao;

import com.onlinetutorialspoint.hibernate.model.Card;
import com.onlinetutorialspoint.hibernate.model.Cheque;
import com.onlinetutorialspoint.hibernate.util.HibernateUtil;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;

public class PaymentDAOImpl implements PaymentDAO {

    public void saveCard(Card card) {
        SessionFactory factory = HibernateUtil.getInstnce();
        Session session = factory.openSession();
        Transaction tx = session.beginTransaction();
        session.save(card);
        tx.commit();
        session.close();
        System.out.println("Card Inserted Successfully..");

    }

    public void saveCheque(Cheque cheque) {
        SessionFactory factory = HibernateUtil.getInstnce();
        Session session = factory.openSession();
        Transaction tx = session.beginTransaction();
        session.save(cheque);
        tx.commit();
        session.close();
        System.out.println("Cheque Inserted Successfully..");
    }

}

PaymentDAOFactory.java

package com.onlinetutorialspoint.hibernate.dao;

public class PaymentDAOFactory {

    public static PaymentDAO getInstance() {
        return new PaymentDAOImpl();
    }
}

Main.java


import com.onlinetutorialspoint.hibernate.dao.PaymentDAO;
import com.onlinetutorialspoint.hibernate.dao.PaymentDAOFactory;
import com.onlinetutorialspoint.hibernate.model.Card;
import com.onlinetutorialspoint.hibernate.model.Cheque;
import java.util.Date;
import org.hibernate.Transaction;

public class Main {

    public static void main(String[] args) {

        Card card = new Card();
        card.setPaymentId(110006);
        card.setPaymentDate(new Date());
        card.setAmount(20000);
        card.setCardNumber(55661423);
        card.setCardType("MASTRO");
        PaymentDAO dao = PaymentDAOFactory.getInstance();
        dao.saveCard(card);

        System.out.println("=========================");

        Cheque cheque = new Cheque();
        cheque.setPaymentId(225612);
        cheque.setPaymentDate(new Date());
        cheque.setAmount(80000);
        cheque.setChequeNumber(45689523);
        cheque.setChequeType("ORDER");
        dao.saveCheque(cheque);
    }
}

Output :

Hibernate: insert into payment (amount, paydate, cardnumber, cardtype, paymode, payid) values (?, ?, ?, ?, 'cp', ?) 
Card Inserted Successfully.. 
========================= 
Hibernate: insert into payment (amount, paydate, chqnumber, chqtype, paymode, payid) values (?, ?, ?, ?, 'chp', ?) 
Cheque Inserted Successfully..

Database :

Table per ClassBy running the above Main class, both Card and Cheque classes are stored in the same table payment. We can differentiate both Card and Cheque information by using the discriminator column.

Happy Learning 🙂

Download Example

About the Author:

Hi Folks, you have reach this so far, that shows you like what you are learning. Then why don't you support us to improve for bettor tutorials by leaving your valuable comments and why not you keep in touch with us for latest updates on your favorite blog @ facebook , twitter , Or Google+ ,

One Comment

  1. nissi.java@gmail.com'
    Nissi February 13, 2018 at 11:13 am - Reply

    This is really great explanation Chandra. Keep it up. I believe you are helping many to grow in their career. May God bless you, If you dont believe God Ignore this statement :-). But Awesome Tutorials!!! Really Appreciate your efforts making simply understandable.!!!

Leave A Comment