0
Sponsored Links


Ad by Google
In my previous post we have seen the Table Per Class Hierarchy Example Using XML here we are going to see the implementation of Table Per Class Hierarchy using annotation. Hibernate supports three basic inheritance mapping strategies
In table per class hierarchy, exactly one table is required even multiple classes are there.

Here is a payment table ER diagram, we are using payment table for this project.

In this project we are using four classes and these are here listed in diagram.

Payment.java is our Super class and three different sub classes are
  1. CardPayment.java
  2. ChequePayment.java
  3. CashPayment.java
For this inheritance hierarchy we are going to use exactly one table. And that table will be payment table.

Tools and Technologies we are using here:

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

Overview of the Project Structure:

Main Objects of this project are:
  • pom.xml
  • hibernate.cfg.xml
  • annotated pojo
  • database
Step 1. Create database script.

CREATE DATABASE `hibernate_tutorial` ;

USE `hibernate_tutorial`;

/*Table structure for table `payment` */

DROP TABLE IF EXISTS `payment`;

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

Step 2. Create a Maven Project:
Step A: Go to File->New->Other..


Step B: Select Maven Project from the select wizard.


Step C: Select project name and location from New Maven Project wizard.


Step D: Configure project provide GroupId, artifactId etc. See the details from the screenshot. This screen shot is from our previous post so here you need to change the artifact Id as Table-Per-Class-Hierarchy-Annotation and project name also as Table-Per-Class-Hierarchy-Annotation.


Step E: After completion of all the above steps, now your project will looks like this screenshot.


3. Add project dependencies into pom.xml file:
Double click on your project's pom.xml file it will looks like this with very limited information.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.javamakeuse.inheritance.annotation</groupId>
  <artifactId>Table-Per-Class-Hierarchy-Annotation</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>Table-Per-Class-Hierarchy-Annotation</name>
  
</project>

Now add Hibernate and MySql dependencies entry inside pom.xml file. Paste the below code inside the project tag of pom.xml file.
<dependencies>
  <!-- Hibernate Dependency -->
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-core</artifactId>
   <version>4.3.7.Final</version>
  </dependency>
  
  <!-- MySql Connector dependency -->
  <dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.10</version>
  </dependency>

 </dependencies>

Here is a complete pom.xml file

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.javamakeuse.inheritance.annotation</groupId>
  <artifactId>Table-Per-Class-Hierarchy-Annotation</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>Table-Per-Class-Hierarchy-Annotation</name>
  
  <dependencies>
  <!-- Hibernate Dependency -->
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-core</artifactId>
   <version>4.3.7.Final</version>
  </dependency>
  
  <!-- MySql Connector dependency -->
  <dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.10</version>
  </dependency>

 </dependencies>

 <build>
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
     <source>1.7</source>
     <target>1.7</target>
    </configuration>
   </plugin>
  </plugins>
 </build>
</project>

Step 4. Create a hibernate.cfg.xml file: Here we placed hibernate.cfg.xml file inside src/main/resources.

<?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 class="com.javamakeuse.annotation.inheritance.pojo.Payment"/>
        <mapping class="com.javamakeuse.annotation.inheritance.pojo.CardPayment"/>
        <mapping class="com.javamakeuse.annotation.inheritance.pojo.ChequePayment"/>
        <mapping class="com.javamakeuse.annotation.inheritance.pojo.CashPayment"/>
          
    </session-factory>
</hibernate-configuration>

Step 5: Create Payment.java pojo class:

package com.javamakeuse.annotation.inheritance.pojo;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name = "payment")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "payment_mode", discriminatorType = DiscriminatorType.STRING)
public class Payment {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 @Column(name = "payment_id")
 private long paymentID;

 @Column(name = "amount")
 private float amount;

 @Column(name = "order_number")
 private String orderNumber;

 @Column(name = "payment_date")
 @Temporal(TemporalType.DATE)
 private Date paymentDate;

 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 + "]";
 }

}

Note: The DiscriminatorColumn contains marker values that tell the persistence layer what subclass to instantiate for a particular row. And DiscriminatorColumn is mandatory here.

Step 6: Now create CardPayment.java sub class

package com.javamakeuse.annotation.inheritance.pojo;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name = "payment")
@DiscriminatorValue("Card")
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 + "]";
 }

}

@DiscriminatorValue("Card") will distinguish the inserted records into the database.

Step 7: Create another sub class ChequePayment.java

package com.javamakeuse.annotation.inheritance.pojo;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name = "payment")
@DiscriminatorValue("Cheque")
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 8: Create another sub class CashPayment.java

package com.javamakeuse.annotation.inheritance.pojo;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name = "payment")
@DiscriminatorValue("Cash")
public class CashPayment extends Payment {

}

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

package com.javamakeuse.annotation.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();

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

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

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

package com.javamakeuse.annotation.inheritance.dao;

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

import com.javamakeuse.annotation.inheritance.pojo.Payment;
import com.javamakeuse.annotation.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 11: Create one more DAO class CardPaymentDAO.java class to fetch the sub class data.

package com.javamakeuse.annotation.inheritance.dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import com.javamakeuse.annotation.inheritance.pojo.CardPayment;
import com.javamakeuse.annotation.inheritance.pojo.Payment;

public class CardPaymentDAO extends PaymentDAO {

 @SuppressWarnings("unchecked")
 public static CardPayment findById(long id) {
  Session session = sessionFactory.openSession();
  List<CardPayment> cardPayment = session.createCriteria(Payment.class)
    .add(Restrictions.eq("class", "Card")).list();

  return cardPayment.get(0);
 }
}

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

package com.javamakeuse.annotation.inheritance.service;

import java.text.SimpleDateFormat;

import com.javamakeuse.annotation.inheritance.dao.CardPaymentDAO;
import com.javamakeuse.annotation.inheritance.dao.PaymentDAO;
import com.javamakeuse.annotation.inheritance.pojo.CardPayment;

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

   // Fetching cardPayment from the database.
   System.out.println(CardPaymentDAO.findById(payment.getPaymentID()));
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

Run the PaymentService.java class it will create a row inside the payment table with payment_mode value as Card

OUT PUT:
Hibernate: 
    insert 
    into
        payment
        (amount, order_number, payment_date, card_type, payment_mode) 
    values
        (?, ?, ?, ?, 'Card')
Hibernate: 
    select
        this_.payment_id as payment_1_0_0_,
        this_.amount as amount3_0_0_,
        this_.order_number as order_nu4_0_0_,
        this_.payment_date as payment_5_0_0_,
        this_.card_type as card_typ6_0_0_,
        this_.bank as bank7_0_0_,
        this_.payment_mode as payment_2_0_0_ 
    from
        payment this_ 
    where
        this_.payment_mode=?
CardPayment [cardType=Debit]



That's it

Download the complete example from here Source Code

References
Reference 1
Reference 2
Reference 3

Sponsored Links

0 comments:

Post a Comment