0
Sponsored Links


Ad by Google
In my previous post we have seen Table Per Class Inheritance Hierarchy Example Using XML. In this post we are going to see the implementation of Table Per Sub Class hierarchy mapping using hbm.xml file. Hibernate supports three basic inheritance mapping strategies
In table per sub class hierarchy, number of classes is equals to number of tables required(example four classes required four tables). The sub class tables have primary key association to the super class table, So the association between super class and sub class is one-to-one and they are mapped with <joined-subclass> element.

Below are the tables ER diagram we are using for this tutorial.

In this project we are using four classes, three sub class and one super class and those are listed here in diagram

Payment.java is our Super class and three different sub classes are-
  1. CardPayment.java
  2. ChequePayment.java
  3. CashPayment.java

Tools and Technologies we are using here:

  • JDK 7
  • Hibernate 4.3.7
  • MySql 5.1.10
  • Eclipse Juno 4.2

Main Objects of this project are:
  • jar files
  • hibernate.cfg.xml
  • *.hbm.xml(mapping files)
  • database

Step 1. Create database script.

CREATE DATABASE `hibernate_tutorial`;

USE `hibernate_tutorial`;

DROP TABLE IF EXISTS `cardpayment`;

CREATE TABLE `cardpayment` (
  `payment_id` bigint(20) NOT NULL,
  `card_type` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`payment_id`),
  CONSTRAINT `FK_7lj2yejd6xxafp2gxmca7ydc0` FOREIGN KEY (`payment_id`) REFERENCES `payment` (`payment_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

/*Table structure for table `cashpayment` */

DROP TABLE IF EXISTS `cashpayment`;

CREATE TABLE `cashpayment` (
  `payment_id` bigint(20) NOT NULL,
  PRIMARY KEY (`payment_id`),
  CONSTRAINT `FK_tim1eyc54hq37ev6488imimmf` FOREIGN KEY (`payment_id`) REFERENCES `payment` (`payment_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

/*Table structure for table `chequepayment` */

DROP TABLE IF EXISTS `chequepayment`;

CREATE TABLE `chequepayment` (
  `payment_id` bigint(20) NOT NULL,
  `bank` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`payment_id`),
  CONSTRAINT `FK_l59sf4vy46sgqqpaf1u0ticlw` FOREIGN KEY (`payment_id`) REFERENCES `payment` (`payment_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

/*Table structure for table `payment` */

DROP TABLE IF EXISTS `payment`;

CREATE TABLE `payment` (
  `payment_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `amount` float DEFAULT NULL,
  `order_number` varchar(255) DEFAULT NULL,
  `payment_date` datetime DEFAULT NULL,
  PRIMARY KEY (`payment_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

Step 2. Create a Java Project
Go to File Menu then New->Java Project, and provide the name of the project.
Note: Screen shot is copied from my previous post, please change your project name something like Table-Per-Sub-Class-XML

Create a lib folder(Optional):
Right click on your project and create a new folder named it as lib,this step is optional this is just to place all the required jar file. You may put all the jar files anywhere in your system's location, In this project we have placed all the required jar files in lib folder.

Step 3. Add libraries(jar files) into project's build path:
required jar files:
  • antlr-2.7.7.jar
  • dom4j-1.6.1.jar
  • hibernate-commons-annotations-4.0.5.Final.jar
  • hibernate-core-4.3.7.Final.jar
  • hibernate-jpa-2.1-api-1.0.0.Final.jar
  • jandex-1.1.0.Final.jar
  • javassist-3.18.1-GA.jar
  • jboss-logging-3.1.3.GA.jar
  • jboss-logging-annotations-1.2.0.Beta1.jar
  • jboss-transaction-api_1.2_spec-1.0.0.Final.jar
  • mysql-connector-java-5.1.3-rc-bin.jar

Step 4. Create a hibernate.cfg.xml file: Here we placed hibernate.cfg.xml file inside com.javamakeuse.hbm.inheritance.xmls package.

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="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate_tutorial</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
         
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
 
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <property name="hbm2ddl.auto">update</property>
        <mapping resource="com/javamakeuse/hbm/inheritance/xmls/Payment.hbm.xml"/>
          
    </session-factory>
</hibernate-configuration>

Step 5. Create Payment.hbm.xml mapping file: Here we placed all the xml files inside com.javamakeuse.hbm.inheritance.xmls package.

Payment.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.javamakeuse.hbm.inheritance.pojo">
 <class name="Payment" table="payment">
  <id name="paymentID" type="java.lang.Long" column="payment_id">
   <generator class="identity" />
  </id>
  <property name="amount" column="amount" type="float" />
  <property name="orderNumber" column="order_number" type="string" />
  <property name="paymentDate" column="payment_date" type="java.util.Date" />

  <joined-subclass name="CashPayment" table="cashpayment">
   <key column="payment_id" />
  </joined-subclass>
  <joined-subclass name="CardPayment" table="cardpayment">
   <key column="payment_id" />
   <property name="cardType" column="card_type" type="string" />
  </joined-subclass>
  <joined-subclass name="ChequePayment" table="chequepayment">
   <key column="payment_id" />
   <property name="bank" column="bank" type="string" />
  </joined-subclass>
 </class>
</hibernate-mapping>

Note: Mapping required <joined-subclass> element with <key> attribute.

Step 6: Create Payment.java pojo class: Payment is our super class.

Payment.java
package com.javamakeuse.hbm.inheritance.pojo;

import java.util.Date;

public abstract class Payment {

 private float amount;
 private String orderNumber;
 private Date paymentDate;
 private long paymentID;

 public long getPaymentID() {
  return paymentID;
 }

 public void setPaymentID(long paymentID) {
  this.paymentID = paymentID;
 }

 public float getAmount() {
  return amount;
 }

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

 public String getOrderNumber() {
  return orderNumber;
 }

 public void setOrderNumber(String orderNumber) {
  this.orderNumber = orderNumber;
 }

 public Date getPaymentDate() {
  return paymentDate;
 }

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

 @Override
 public String toString() {
  return "Payment [amount=" + amount + ", orderNumber=" + orderNumber
    + ", paymentDate=" + paymentDate + "]";
 }

}

Step 7: Now create CardPayment.java sub class

package com.javamakeuse.hbm.inheritance.pojo;

public class CardPayment extends Payment {
 private String cardType;

 public String getCardType() {
  return cardType;
 }

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

 @Override
 public String toString() {
  return "CardPayment [cardType=" + cardType + "]";
 }

}

Step 8: Create another sub class ChequePayment.java

package com.javamakeuse.hbm.inheritance.pojo;

public class ChequePayment extends Payment {
 private String bank;

 public String getBank() {
  return bank;
 }

 public void setBank(String bank) {
  this.bank = bank;
 }

 @Override
 public String toString() {
  return "ChequePayment [bank=" + bank + "]";
 }

}

Step 9: Create one more sub class CashPayment.java

package com.javamakeuse.hbm.inheritance.pojo;

public class CashPayment extends Payment{

}

Step 10: Create HibernateUtility.java class to build sessionFactory via loading configuration file.

package com.javamakeuse.hbm.inheritance.utils;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class HibernateUtility {
 private static final SessionFactory sessionFactory = buildSessionFactory();

 private static SessionFactory buildSessionFactory() {
  Configuration configuration = new Configuration();
  configuration.configure("/com/javamakeuse/hbm/inheritance/xmls/hibernate.cfg.xml");

  ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
    .applySettings(configuration.getProperties()).build();
  SessionFactory sessionFactory = configuration
    .buildSessionFactory(serviceRegistry);
  return sessionFactory;
 }

 public static SessionFactory getSessionFactory() {
  return sessionFactory;
 }
}

Step 11: Create PaymentDAO.java class to perform the CRUD operations

package com.javamakeuse.hbm.inheritance.dao;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.javamakeuse.hbm.inheritance.pojo.Payment;
import com.javamakeuse.hbm.inheritance.utils.HibernateUtility;

public class PaymentDAO {
 static SessionFactory sessionFactory;
 static {
  sessionFactory = HibernateUtility.getSessionFactory();
 }

 public static Payment save(Payment payment) {
  Session session = sessionFactory.openSession();

  session.beginTransaction();

  session.save(payment);

  session.getTransaction().commit();

  return payment;
 }

 public static Payment update(Payment payment) {
  Session session = sessionFactory.openSession();

  session.beginTransaction();

  session.merge(payment);

  session.getTransaction().commit();

  return payment;

 }

 public static void delete(Payment payment) {
  Session session = sessionFactory.openSession();

  session.beginTransaction();

  session.delete(payment);

  session.getTransaction().commit();

 }

}

Step 12: Create PaymentService.java class to call the methods of DAO class.

PaymentService.java
package com.javamakeuse.hbm.inheritance.service;

import java.text.SimpleDateFormat;

import com.javamakeuse.hbm.inheritance.dao.PaymentDAO;
import com.javamakeuse.hbm.inheritance.pojo.CardPayment;

public class PaymentService {
 public static void main(String[] args) {
  try {
   SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
   // using CardPayment
   CardPayment payment = new CardPayment();
   payment.setCardType("Debit");
   payment.setAmount(250);
   payment.setOrderNumber("WO0001");
   payment.setPaymentDate(sdf.parse("2015-01-01"));

   // using ChequePayment
   /*
    * ChequePayment payment = new ChequePayment();
    * payment.setBank("SBI");
    */

   // using CashPayment
   /*
    * CashPayment payment = new CashPayment(); payment.setAmount(250);
    */

   
   PaymentDAO.save(payment);

  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

Note: Before inserting record into sub class it will insert row inside super class and place the super class id into sub class.

Run the PaymentService.java class it will  generate two insert query one for super class(payment ) and one for sub class(cardpayment)

OUT PUT:
Hibernate: 
    insert 
    into
        payment
        (amount, order_number, payment_date) 
    values
        (?, ?, ?)
Hibernate: 
    insert 
    into
        cardpayment
        (card_type, payment_id) 
    values
        (?, ?)

payment table:

cardpayment table:


That's it

Download the complete example from here Source Code Only

References
Reference 1
Reference 2
Sponsored Links

0 comments:

Post a Comment