[Example-Lab] Table Per Class Inheritance Strategy in Hibernate 4.3

In the TABLE_PER_CLASS strategy, hibernate will create a separate table for all the classes in an inheritance hierarchy. It is still not normalized completely as inherited columns are repeated in all tables. For instance, Fields inherited from Shape such as id and fillcolor are repeated in all the tables.

In this example, we will create and save three entity classes – Shape, Rectangle and Circle; where Rectangle and Circle extends from Shape.

If you are not following the tutorials in order, refer to the article http://javajee.com/your-first-hibernate-43-program for the basic setup including hibernate configuration file.


Configuration file changes

You should replace the user class in the configuration file with Shape, Rectangle and Circle classes as:

<!-- Names the annotated entity class -->

<mapping class="com.javajee.hiberex.dto.Shape"/>

<mapping class="com.javajee.hiberex.dto.Rectangle"/>

<mapping class="com.javajee.hiberex.dto.Circle"/>

Else you will get org.hibernate.MappingException: Unknown entity:…


Shape class

The base entity class, shape will have id and fillcolor properties:


@Inheritance (strategy = InheritanceType.TABLE_PER_CLASS)

public class Shape {

  @Id @GeneratedValue(strategy=GenerationType.TABLE)

  int shapeId;

  String fillcolor;

 //Getters and setters not shown here; create them manually or generate in eclipse.


Since I am using MySQL database, I am need to use @GeneratedValue(strategy=GenerationType.TABLE) for TABLE_PER_CLASS strategy. With other databases, just @GeneratedValue as in SINGLE_TABLE strategy might just work. 


Rectangle class

Entity class Rectangle extends from Shape, and have length and breadth properties:


public class Rectangle extends Shape{

  long length;

  long breadth;

//Getters and setters not shown here; create them manually or generate in eclipse.


This class is same as in SINGLE_TABLE strategy without @DiscriminatorValue annotation.


Circle class

Entity class Circle extends from Shape, and has one property radius:


public class Circle extends Shape{

  long radius;

//Getters and setters not shown here; create them manually or generate in eclipse.


This class is same as in SINGLE_TABLE strategy without @DiscriminatorValue annotation.


Test class

Now use the below test class to create objects for these classes, populate data and save them:

public class ShapeTest {

  public static void main(String[] args) {

    Shape s = new Shape();


    Rectangle r = new Rectangle();



    Circle c = new Circle();


    Configuration configuration = new Configuration();


    ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()

    SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);

    Session session = sessionFactory.openSession();







This class is same as in SINGLE_TABLE strategy.


Verifying the results

When you execute the above test class, below queries are executed by hibernate (as seen from the console):

Hibernate: insert into Shape (fillcolor, shapeId) values (?, ?)

Hibernate: insert into Rectangle (fillcolor, breadth, length, shapeId) values (?, ?, ?, ?)

Hibernate: insert into Circle (fillcolor, radius, shapeId) values (?, ?, ?)


You can see that hibernate has created one table each for Shape, Rectangle and Circle.  

Also, Shape’s fillcolor and shapeId, which are inherited by all, appears in all the tables.

Things will be more clear, once you see the database snapshot. Just do a select all query (select * from Shape/Rectangle/Circle).

This is better than SINGLE_TABLE as it eliminated irrelevant columns with NULL values, but this can still be normalized using joins.


Search the Web

Custom Search

Searches whole web. Use the search in the right sidebar to search only within javajee.com!!!