Arpit Mandliya

About Arpit Mandliya

I am java developer at Tata Consultancy Services Ltd. My current area of interest are J2EE,web development and java design patterns. I am technology enthusiast trying to explore new technologies. In spare time,I love blogging.

Hibernate inheritance: Table per class hierarchy

In this tutorial we will see how to implement inheritance in hibernate.There are 3 ways in which you can implement inheritance in hibernate.In this post,we will see one of them i.e.one table per class hierarchy.

Inheritance in hibernate:

Java is object oriented language and inheritance is one of main functionalities of java.Relation model can implement ‘is a’ and ‘has a’ relationship but hibernate provides us way to implement class hierarchy in a different ways.
 
 

One table per class hierarchy:

Lets say we have following class hierarchy.We have shape class as base class and Rectangle and Circle inherit from Shape class.

In one table per class hierarchy,One table will be created for above hierarchy.i.e. SHAPE table will be created having following structure.

As you can see only one table(SHAPE) is created having attributes of subclasses also. As per our above class diagram,we will create three classes-Shape.java,Rectangle.java and Circle.java

1.Shape.java

This is our root class of entity class hierarchy.

Create Shape.java in src->org.arpit.javapostsforlearning.

package org.arpit.javapostsforlearning;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import javax.persistence.DiscriminatorType;

@Entity
@Table(name='SHAPE')
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn
(
 name='Discriminator',
 discriminatorType=DiscriminatorType.STRING
)
@DiscriminatorValue(value='S')
public class Shape {

 @Id
 @GeneratedValue
 @Column(name='Shape_Id')
 int shapeId;
 @Column(name='Shape_Name')
 String shapeName;

        public Shape()
 {

 } 
 public Shape(String shapeName)
 {
  this.shapeName=shapeName;
 }
 //getters and setters

}

Shape is our root class so some annotations needs to be used with root class for implementing inheritance.

@Inheritance:

For implementing inheritance in hiberante,@Inheritance annotation is used.It defines inheritance strategy to be implement for entity class hierarchy.For one table per class hierarhcy,we have used Single_Table as inheritance strategy.This annotation is defined at root level or sub hierarchy level where different strategy is to be applied.

@DiscriminatorColumn:

This annotation is used to define discriminator column for Single_Table and joined strategy.It is used to distinguish between different class instances.This annotation is defined at root level or sub hierarchy level where different strategy is to be applied. If @DiscriminatorColumn annotation is not specified,then hibernate will create a column named as ‘DType’ and DiscriminatorType will be string.

@DiscriminatorValue:

This annotation defines value in discriminator column for that class.This can only be applied on entity concrete class.For example,If entry will be of shape instance in SHAPE table then ‘s’ will be value for that row in discriminator column.If this annotation is not specified and Discriminator column is used then provider specific values will be provided and if Discriminator type is String then discriminator value will be entity name.Discriminator value,if not defaulted need to specified on each enitity in hierarchy.

2.Rectangle.java

This is our child class.

Create Rectangle.java in src->org.arpit.javapostsforlearning.

package org.arpit.javapostsforlearning;import javax.persistence.Column;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue(value='R')
public class Rectangle extends Shape{

 @Column(name='Rectangle_Length')
 int length;
 @Column(name='Rectangle_Breadth')
 int breadth;
 // getters and setters

 public Rectangle()
 {

 }

 public Rectangle(String shapeName,int length,int breadth)
 {
  super(shapeName);
  this.length=length;
  this.breadth=breadth;
 }

 // getters and setters
}

3.Circle.java

This is our second child class.

Create Circle.javain src->org.arpit.javapostsforlearning.

package org.arpit.javapostsforlearning;import javax.persistence.Column;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue(value="R")
public class Rectangle extends Shape{

 @Column(name="Rectangle_Length")
 int length;
 @Column(name="Rectangle_Breadth")
 int breadth;
 // getters and setters
 
 public Rectangle()
 {
  
 }
 
 public Rectangle(String shapeName,int length,int breadth)
 {
  super(shapeName);
  this.length=length;
  this.breadth=breadth;
 }
 
 // getters and setters
}

4.Hiberante.cfg.xml:

Create a file named ‘hibernate.cfg.xml’ in src folder.

<?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>

        <!-- Database connection settings -->
        <property name='connection.driver_class'>com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
        <property name='connection.url'>jdbc:sqlserver://localhost:1433;database=UserInfo</property>
        <property name='connection.username'>sa</property>
        <property name='connection.password'></property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name='connection.pool_size'>1</property>

        <!-- SQL dialect -->
        <property name='dialect'>org.hibernate.dialect.SQLServer2005Dialect</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name='current_session_context_class'>thread</property>

        <!-- Disable the second-level cache  -->
        <property name='cache.provider_class'>org.hibernate.cache.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name='show_sql'>true</property>

        <!-- Drop and re-create the database schema on startup -->
        <property name='hbm2ddl.auto'>create</property>

  <mapping class='org.arpit.javapostsforlearning.Shape'></mapping>
  <mapping class='org.arpit.javapostsforlearning.Rectangle'></mapping>
  <mapping class='org.arpit.javapostsforlearning.Circle'></mapping>

    </session-factory>

</hibernate-configuration>

5.Main Class:

package org.arpit.javapostsforlearning;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

public class HibernateMain {

 public static void main(String[] args) {

  Shape shape=new Shape('Sqaure');
  Rectangle rectangle=new Rectangle('Rectangle', 10, 20);  
  Circle circle=new Circle('Circle', 4);

  Configuration configuration=new Configuration();
  configuration.configure();
  ServiceRegistry sr= new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
  SessionFactory sf=configuration.buildSessionFactory(sr);
  Session ss=sf.openSession();

  ss.beginTransaction();
  ss.save(shape);
  ss.save(rectangle);
  ss.save(circle);
  ss.getTransaction().commit();
  ss.close();

 }
}

6.Run it:

When you run it,you will get following output.

Hibernate: create table SHAPE (Discriminator varchar(31) not null, Shape_Id int identity not null, Shape_Name varchar(255), Rectangle_Breadth int, Rectangle_Length int, Circle_Radius int, primary key (Shape_Id))
Feb 04, 2013 11:01:36 PM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000230: Schema export complete
Hibernate: insert into SHAPE (Shape_Name, Discriminator) values (?, 'S')
Hibernate: insert into SHAPE (Shape_Name, Rectangle_Breadth, Rectangle_Length, Discriminator) values (?, ?, ?, 'R')
Hibernate: insert into SHAPE (Shape_Name, Circle_Radius, Discriminator) values (?, ?, 'C')

7.SQL output:

SHAPE table in database.

 

Reference: Hibernate inheritance: Table per class hierarchy from our JCG partner Arpit Mandliya at the Java frameworks and design patterns for beginners blog.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

3 Responses to "Hibernate inheritance: Table per class hierarchy"

  1. Brian Crook says:

    Correct me if I’m wrong, but shouldn’t the discriminator on Circle be “C”, not “R”?

  2. Nkunzis says:

    In circle.java class u have used rectangle.java’s codes.

Leave a Reply


+ 7 = sixteen



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books