Pages Navigation Menu

Coding is much easier than you think

Table per Class Hierarchy Using Annotation

Posted by on May 20, 2015 in Hibernate, Hibernate Annotation | 0 comments

Table per class hierarchy
 
In our previous tutorial we got introduced to Inheritance Mapping In Hibernate, In this article I will explain you about Table per Class Hierarchy Inheritance mapping. By this inheritance strategy, we can map the whole hierarchy in a single table. Here, an extra column otherwise known as discriminator column is created in the table to identify the class. In the table, for each record some columns will be empty; those columns for which the particular Java class does not have fields.
 
Inheritance
 
The above is the Hierarchy of classes involved. Here Employee is the super class for PermanentEmployee and ContractEmployee classes. Now Let us create Java classes for the above hierarchy to implement
 

Entity class

 
File: Employee.java

package entity;

import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
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;

@Entity
@Table(name = "EMPLOYEE")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue(value = "")
public class Employee {

	@Id
	@GeneratedValue
	@Column(name = "EMPID")
	private int empID;

	@Column(name = "EMP_NAME")
	private String empName;

	public int getEmpID() {
		return empID;
	}

	public String getEmpName() {
		return empName;
	}

	public void setEmpID(int empID) {
		this.empID = empID;
	}

	public void setEmpName(String empName) {
		this.empName = empName;
	}
}

 
In case of table per class hierarchy a discriminator column is added by the hibernate framework that specifies the type of the record. It is mainly used to identify which derived class object have been saved in the table (see Database screen shot for better understanding). To specify this, following annotation where used in Super class entity.
 
@Inheritance – Defines the inheritance strategy to be used for an entity class hierarchy. It is specified on the entity class that is the root of the entity class hierarchy.

@DiscriminatorColumn – Is used to define the discriminator column for the SINGLE_TABLE and JOINED inheritance mapping strategies. The strategy and the discriminator column are only specified in the root of an entity class hierarchy or sub hierarchy in which a different inheritance strategy is applied

If the @DiscriminatorColumn annotation is missing, and a discriminator column is required, the name of the discriminator column defaults to “DTYPE” and the discriminator type to DiscriminatorType.STRING.

@DiscriminatorValue – Is used to specify the value of the discriminator column for entities of the given type. The DiscriminatorValue annotation can only be specified on a concrete entity class. If the DiscriminatorValue annotation is not specified and a discriminator column is used, a provider-specific function will be used to generate a value representing the entity type. If the DiscriminatorType is STRING, the discriminator value default is the entity name.

The inheritance strategy and the discriminator column are only specified in the root of an entity class hierarchy or subhierarchy in which a different inheritance strategy is applied. The discriminator value, if not defaulted, should be specified for each entity class in the hierarchy.
 
File: PermanentEmployee.java

package entity;

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

@Entity
@Table(name = "EMPLOYEE")
@DiscriminatorValue("Permanent Employee")
public class PermanentEmployee extends Employee {

	@Column(name = "COMPANY_NAME")
	private String companyName;

	public String getCompanyName() {
		return companyName;
	}

	public void setCompanyName(String companyName) {
		this.companyName = companyName;
	}
}

 
PermanentEmployee class is child of Employee class. Thus while specifying the mappings, we used @DiscriminatorValue to specify discriminator value. In our case “Permanent Employee” will be persisted in discriminator column.
 
File: ContractEmployee.java

package entity;

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

@Entity
@Table(name = "EMPLOYEE")
@DiscriminatorValue("Contract Employee")
public class ContractEmployee extends Employee {

	@Column(name = "CONTRACTOR_NAME")
	private String contractorName;

	public String getContractorName() {
		return contractorName;
	}

	public void setContractorName(String contractorName) {
		this.contractorName = contractorName;
	}
}

 

Hibernate Configuration file

 

<hibernate-configuration>
<session-factory>
	<!-- Database connection settings -->
	<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
	<property name="hibernate.connection.username">system</property>
	<property name="hibernate.connection.password">admin</property>
	<property name="hibernate.connection.url">jdbc:oracle:thin:@xxx.x.x.x:1521:XE</property>

	<!-- SQL dialect -->
	<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>

	<!-- Echo all executed SQL to sysout -->
	<property name="show_sql">true</property>

	<!-- Drop and re-create the database schema on startup -->
	<property name="hibernate.hbm2ddl.auto">create</property>
	<!-- Map Entity Class -->
       <mapping class="entity.Employee"></mapping>
       <mapping class="entity.PermanentEmployee"></mapping>
       <mapping class="entity.ContractEmployee"></mapping>

</session-factory>
</hibernate-configuration>

 
The hbm2ddl.auto property is defined for creating automatic table in the database.
 

Client program

 
Create the class that stores the persistent object in this class, we are simply storing the employee objects in the database.
 

package util;

import entity.ContractEmployee;
import entity.PermanentEmployee;

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

public class HibernateUtil {

	public static void main(String[] args) {

		Configuration cf = new Configuration().configure("hibernate.cfg.xml");

		StandardServiceRegistryBuilder srb = new StandardServiceRegistryBuilder();
		srb.applySettings(cf.getProperties());
		ServiceRegistry sr = srb.build();
		SessionFactory sf = cf.buildSessionFactory(sr);

		Session session = sf.openSession();

		PermanentEmployee p1 = new PermanentEmployee();
		p1.setEmpID(1);
		p1.setEmpName("Ameer");
		p1.setCompanyName("CTS");

		PermanentEmployee p2 = new PermanentEmployee();
		p2.setEmpID(2);
		p2.setEmpName("Lourde");
		p2.setCompanyName("TCS");

		// create two objects of ContractEmployee
		ContractEmployee t1 = new ContractEmployee();
		t1.setEmpID(3);
		t1.setEmpName("Prabhu");
		t1.setContractorName("ABD Consultancy");

		ContractEmployee t2 = new ContractEmployee();
		t2.setEmpID(4);
		t2.setEmpName("Badru");
		t2.setContractorName("MN Consultancy");

		Transaction tx = session.beginTransaction();

		session.save(p1);
		session.save(p2);
		session.save(t1);
		session.save(t2);

		tx.commit();
		System.out.println("Object saved successfully !");
		session.close();
		sf.close();
	}
}

 

Eclipse Console

 
eclipse console

Database output

 
table-per-class

Read More

Hibernate 4 Hello World example in Eclipse using Annotation

Posted by on May 20, 2015 in Hibernate | 1 comment

Hibernate Hello world
 
This is the 4th article on Hibernate in java application that describes on how to to save an object from java into the database using Hibernate 4(Hibernate 4 Insert Query). If you have not read my previous articles article on Generic Hibernate Application Requirements and Steps to be followed to use Hibernate in Java, I will recommend that you read that article first. You may want to look at Hibernate Installation/Setup on Eclipse IDE article if Hibernate is not installed already on your system.
 
As described earlier, the following files are the minimum requirement to shape an hibernate program..
 
StudentEntity.java (Entity class)
hibernate.cfg.xml (Xml configuration file)
HibernateUtil.java (Main class to access this configuration file and to write hibernate logic)
 

Project Structure

 
The final appearance of the application should be as follows:
 
HibernateHelloWorld
 

Entity class

 

package entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "STUDENT")
public class StudentEntity {

	@Id
	@Column(name = "ID")
	private int id;
	
	@Column(name = "NAME")
	private String name;
	
	@Column(name = "DEPARTMENT")
	private String department;
	
	@Column(name = "COLLEGE")
	private String college;

// Create Getters and Setters
}

 
Note: I have explained about every annotations used in the above file in the article Generic Hibernate Application Requirements
 

Hibernate Configuration file

 
Create a new XML file and give this new configuration file the default name hibernate.cfg.xml and place it src directory of your project.
 
File: hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>
	<!-- Database connection settings -->
	<property name="hibernate.connection.driver_class">
                  oracle.jdbc.driver.OracleDriver
        </property>
	<property name="hibernate.connection.username">system</property>
	<property name="hibernate.connection.password">admin</property>
	<property name="hibernate.connection.url">
                   jdbc:oracle:thin:@xxx.x.x.x:1521:XE
        </property>

	<!-- SQL dialect -->
	<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>

	<!-- Echo all executed SQL to sysout -->
	<property name="show_sql">true</property>

	<!-- Drop and re-create the database schema on startup -->
	<property name="hibernate.hbm2ddl.auto">update</property>
	<!-- Map Entity Class -->
    <mapping class="entity.StudentEntity"></mapping>

</session-factory>
</hibernate-configuration>

 

Hibernate Utility

 
Create the Main class to run the example.
 

package util;

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

import entity.StudentEntity;

public class HibernateUtil {

	public static void main(String[] args) {

        Configuration cf = new Configuration().configure("hibernate.cfg.xml");

        StandardServiceRegistryBuilder srb = new StandardServiceRegistryBuilder();
        srb.applySettings(cf.getProperties());
        ServiceRegistry sr = srb.build();
        SessionFactory sf = cf.buildSessionFactory(sr);

        Session session = sf.openSession();
    
        StudentEntity std = new StudentEntity();
		std.setId(24); // Primary Key
		std.setName("Jamil");
		std.setDepartment("ECE");
		std.setCollege("SKCET");

		Transaction tx = session.beginTransaction();
		session.save(std);
		tx.commit();
		System.out.println("Object saved successfully.....!!");
		session.close();
		sf.close();
	}
}

 
In the article Steps to be followed to use Hibernate in Java, I have explained the configuration/code used in above program in detail.
 
Now once our project is ready. Right click to project or right click to HibernateUtil.java and click Run As–>Java Application. Since I have set show_sql to true in hibernate.cfg.xml, so the hibernate create and insert quires will be displayed on eclipse console as below.
 
Hibernate Console
 
You will see the data stored in Student table in the database.
 
Hibernate Result
 
In my next article I have implemented Select Query in Hibernate
 

Read More

Generic Hibernate Application Requirements – XML Mapping

Posted by on May 20, 2015 in Hibernate, Hibernate XML Mapping | 0 comments

Hibernate Generic Requirment
 
The objective of this example is to understand the general requirement to be followed in creating any hibernate application in Java. You may want to look at Hibernate Installation/Setup on Eclipse IDE article if Hibernate is not installed already on your system.
 
In general any hibernate application, must have the following 4 files,

Model class
Mapping XML
Configuration XML
One java file to access this configuration file/write our logic

These files are the minimum requirement to run an hibernate application, in case of complex application we may require many Model classes and many mapping xml files, one configuration xml and a java program to access the configuration details and to write our logic.

Note : Number of Model classes = Number of mapping xml files
 

Model class

 
Model class is simple POJO (Plane old java object), that does extend any class or implement any interface, for each member variable defined in this class you must create a getter and a setter.
 
Example:Student.java
 

package model;

public class Student {
	private int id;
	private String name;
	private String department;
	private String college;

// Create Getters and Setters
}

 

Hibernate Mapping file for Model Class

 
The mapping file is where the Hibernate mapping comes into play, this mapping file tells Hibernate what table in the database it has to access, and what columns in that table it should use.
 
Student.hbm.xml : A simple hibernate XML mapping
 

<?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>
	<class name="model.Student" table="STUDENT">
		<id name="id" column="STUDENT_ID">
			<generator class="assigned" />
		</id>
		<property name="name" column="STUDENT_NAME" />
		<property name="department" />
		<property name="college" />
	</class>
</hibernate-mapping>

 
As shown above, the mapping file contains several elements, listed below are its role:

  • Class element takes care of mapping Student class from java side to STUDENT table in the database
  • Id element, indicates which column in database table we need to take as primary key column.
    In the property name of “id” element we need to give the member variable name from the student class(id) which will mapped with STUDENT_ID column in the STUDENT table.
     
    In the above example “id” member variable of Student class is mapped with STUDENT_ID Column of database, and this STUDENT_ID is the primary key of the table STUDENT.
     
    Note:
    I will explain about this <generator /> element later.
     
  • Property element, used from non-primary key mapping , in this example name member variable is mapped to “STUDENT_NAME” of STUDENT table.
     
    Question: Why does id and name property mapping include the column attribute, but the department and college does not?
    Answer: Without the column attribute, Hibernate by default uses the property name as the column name. This works for department and college , however if we have a member variable called date in java class, now this date is a reserved keyword in most of the database, so you will need to map it to a different name, so in such scenarios we can go for column attribute in xml mapping.

 

Hibernate Configuration file

 
In this mapping file Hibernate gets to know about the type of database and its connection properties as well as about the mapping files.
 
File: hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>
   <!-- Database connection settings -->
   <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
   <property name="hibernate.connection.username">system</property>
   <property name="hibernate.connection.password">admin</property>
   <property name="hibernate.connection.url">jdbc:oracle:thin:@127.0.0.1:1521:XE</property>

   <!-- SQL dialect -->
   <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>

   <!-- Echo all executed SQL to sysout -->
   <property name="show_sql">true</property>

   <!-- Create/Update the database schema on startup -->
   <property name="hibernate.hbm2ddl.auto">update</property>
   <!-- Mapping file -->
   <mapping resource="Student.hbm.xml" />

</session-factory>

</hibernate-configuration>

 
In our next article we shall learn about Generic Steps to be followed to use Hibernate in any Java application, going forward using this two articles we shall implement Hello World example of Hibernate 4 in Eclipse

Read More

Different Between Session.Get() and Session.Load() in Hibernate

Posted by on Apr 23, 2015 in Hibernate | 0 comments

Get Vs Load in hibernate
 
Often times, you will notice Hibernate developers mix use of session.get() and session load()
 
At first look both get() and load() seems similar because both of them fetch the data from database, however there are few differences between them, let’s look at those difference with simple example.
 

package util;

import entity.StudentEntity;

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

public class GetVsLoad {

	public static void main(String[] args) {

		Configuration cf = new Configuration().configure("hibernate.cfg.xml");

		StandardServiceRegistryBuilder srb = new StandardServiceRegistryBuilder();
		srb.applySettings(cf.getProperties());
		ServiceRegistry sr = srb.build();
		SessionFactory sf = cf.buildSessionFactory(sr);

		Session session = sf.openSession();
	
		// Get Example
		System.out.println("Student get called");

		StudentEntity student1 = (StudentEntity) session.get(StudentEntity.class, 1);
		System.out.println("Student ID= " + student1.getId());
		System.out.println("Student Get Details - " + student1 + "n");

		// load Example
		System.out.println("Student load called");
		StudentEntity student2 = (StudentEntity) session.load(StudentEntity.class, 2);
		System.out.println("Student ID= " + student2.getId());
		System.out.println("Student load Details - " + student2 + "n");

		// Close resources
		session.close();
		sf.close();
	}
}

 
Get-Vs-Load
 
From the output it’s clear that get() returns the object by fetching it from database whereas load() method will not hit the database (no select statement in output before printing ID) to retrieve the StudentEntity object, it will return a StudentEntity proxy object – a fake object created by hibernate with given identifier value(ID = 2).
 
In the above example we have called StudentEntity student2 = (StudentEntity) session.load(StudentEntity.class, 2); So here hibernate will create one fake StudentEntity object in the memory with id 2, but the other properties of StudentEntity class will not be initialized.
 
This method loads the data from database only when we try to access other properties of the StudentEntity object(Ex:- name, department, college). In the above example the DB hit takes place only after we try to call other member variable of StudentEntity object.
 

Now let’s try to fetch data that doesn’t exists in the database

 
Get Example
 

// Get Example
try {
	System.out.println("Session.get example");
	StudentEntity std = (StudentEntity) session.get(StudentEntity.class, 100);

	if (std == null) {
	System.out.println("Student Details not Found !! ");	
	} 
	else
	{
		System.out.println("Student Details Found !! ");	
		System.out.println("Student GET ID= " + std.getId());
		System.out.println("Student Get Details - " + std + "n");
	}
} catch (Exception e) {
	e.printStackTrace();
}

 
Load Example
 

// load Example
try {
	System.out.println("nSession.load example");
	StudentEntity std2 = (StudentEntity) session.load(StudentEntity.class, 100);

	if (std2 == null) {
		System.out.println("Student Details not Found !! ");
	}
	else
	{
		System.out.println("Student Details Found !! ");
		System.out.println("Student LOAD ID= " + std2.getId());
		System.out.println("Student load Details - " + std2 + "n");
	}
	
} catch (Exception e) {
	e.printStackTrace();
}

 
Above code produces following output.
 
Get Vs Load2
 
In the above program when we use get() to retrieve data that doesn’t exists, it returns null. That makes sense because it try to load the data as soon as it’s called.
 
But With load(), we are able to print the ID; but as soon as we try to access other fields, it fires database query and throws org.hibernate.ObjectNotFoundException when there is no record found with the given identifier.
 
Another must read
Hibernate Eager vs Lazy Fetch Type
 

Special cases

 
If get(StudentEntity.class, 1) is called first and later again load(StudentEntity.class, 1) is called and if the record with primary key 1 exists, the s1 in the both the cases contains a real object. Why? We know get() method returns a StudentEntity object and load() returns s proxy object. With get(), a real object exists in the cache memory, the same object is returned to load() also.
If the reverse happens? If load() is called first and then get()? In both cases, s1 contains a proxy object because first load() returns a proxy and remains in the cache memory.
 

Summary

  • get() loads the data from database as soon as it’s called whereas load() returns a proxy object and loads data only from database when it’s actually required, so load() is better because it support lazy loading.
  • Since load() throws exception when data is not found, we should use it only when we know data exists.
  • We should not use load method to determine if an instance exists (use get() instead). Use this only to retrieve an instance that you assume exists, where non-existence would be an actual error.
  • Both methods are used to retrieve only one Java object (record) from the database (for multiple records, we have, list() and iterate() methods).

 

Read More

Table per Concrete Class Example using XML – Hibernate4

Posted by on Apr 19, 2015 in Hibernate | 0 comments

Table per Concrete Class
 
In case of Table per concrete class, two tables for each subclass are created. The super class variables are placed in each subclass.
 
In this example, we are going to use hb2ddl.auto property to generate the table automatically. So we don’t need to worry about creating tables in the database.
 
Inheritance
 
The above is the Hierarchy of classes involved. Here Employee is the super class for PermanentEmployee and ContractEmployee classes. Now Let us create Java classes for the above hierarchy to implement
 

Model class

 
File: Employee.java

package model;

public class Employee {
	private int empID;
	private String empName;

	public int getEmpID() {
		return empID;
	}

	public String getEmpName() {
		return empName;
	}

	public void setEmpID(int empID) {
		this.empID = empID;
	}

	public void setEmpName(String empName) {
		this.empName = empName;
	}

}

 
File: PermanentEmployee.java

package model;

public class PermanentEmployee extends Employee {
	private String companyName;

	public String getCompanyName() {
		return companyName;
	}

	public void setCompanyName(String companyName) {
		this.companyName = companyName;
	}

}

 
File: ContractEmployee.java

package model;

public class ContractEmployee extends Employee {
	String contractorName;

	public String getContractorName() {
		return contractorName;
	}

	public void setContractorName(String contractorName) {
		this.contractorName = contractorName;
	}
}

 

Hibernate Mapping xml

 

<hibernate-mapping>
	<class name="model.Employee" table="EMPLOYEE">
		<id name="empID" type="int" column="EMPID">
			<generator class="assigned" />
		</id>
		
		<property name="empName" type="java.lang.String" column="EMP_NAME" />

		<union-subclass name="model.PermanentEmployee" table="P_EMPLOYEE">
			<property name="companyName" column="COMPANY_NAME" />
		</union-subclass>
		
		<union-subclass name="model.ContractEmployee" table="T_EMPLOYEE">
			<property name="contractorName" column="CONTRACTOR_NAME" />
		</union-subclass>
		
	</class>
</hibernate-mapping>

 
The union-subclass sub element of class, specifies the subclass. It adds the columns of parent table into this table. In other words, it is working as a union.class.
 

Hibernate Configuration file

 

<hibernate-configuration>

	<session-factory>
		<!-- Database connection settings -->
		<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
		<property name="hibernate.connection.username">system</property>
		<property name="hibernate.connection.password">admin</property>
		<property name="hibernate.connection.url">jdbc:oracle:thin:@127.0.0.1:1521:XE</property>

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

		<!-- SQL dialect -->
		<property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>

		<!-- Enable Hibernate's current session context -->
		<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 sysout -->
		<property name="show_sql">true</property>

		<!-- Drop and re-create the database schema on startup -->
		<property name="hibernate.hbm2ddl.auto">create</property>
		<mapping resource="Employee.hbm.xml" />

	</session-factory>

</hibernate-configuration>

 
The hbm2ddl.auto property is defined for creating automatic table in the database.
 

Client program

 
Now let us write one client program for three bean programs – Employee, PermanentEmployee, ContractEmployee
 

package util;

import model.ContractEmployee;
import model.PermanentEmployee;

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

public class HibernateUtil {

	public static void main(String[] args) {

		Configuration cf = new Configuration().configure("hibernate.cfg.xml");

		StandardServiceRegistryBuilder srb = new StandardServiceRegistryBuilder();
		srb.applySettings(cf.getProperties());
		ServiceRegistry sr = srb.build();
		SessionFactory sf = cf.buildSessionFactory(sr);

		Session session = sf.openSession();

		PermanentEmployee p1 = new PermanentEmployee();
		p1.setEmpID(1);
		p1.setEmpName("Ameer");
		p1.setCompanyName("CTS");

		PermanentEmployee p2 = new PermanentEmployee();
		p2.setEmpID(2);
		p2.setEmpName("Lourde");
		p2.setCompanyName("TCS");

		// create two objects of ContractEmployee
		ContractEmployee t1 = new ContractEmployee();
		t1.setEmpID(3);
		t1.setEmpName("Prabhu");
		t1.setContractorName("ABD Consultancy");

		ContractEmployee t2 = new ContractEmployee();
		t2.setEmpID(4);
		t2.setEmpName("Badru");
		t2.setContractorName("MN Consultancy");

		Transaction tx = session.beginTransaction();

		session.save(p1);
		session.save(p2);
		session.save(t1);
		session.save(t2);

		tx.commit();
		System.out.println("Object saved successfully !");
		session.close();
		sf.close();
	}
}

 

Eclipse Console

 
Table per Concrete Class Example using XML - Hibernate4

Database output

 
P_EMPLOYEE2
 
T_Employee2
 

Read More

Table per Subclass Example using XML file

Posted by on Apr 16, 2015 in Hibernate | 0 comments

Table per Sub Class
 
In case of Table per Subclass, subclass mapped tables are related to parent class table by primary key and foreign key relationship.
 
The <joined-subclass> element of class is used to map the child class with parent using the primary key and foreign key relation.
 
In this example, we are going to use hb2ddl.auto property to generate the table automatically. So we don’t need to worry about creating tables in the database.
 
Let’s see the hierarchy of classes that we are going to map.
 
The above is the Hierarchy of classes involved. Here Employee is the super class for PermanentEmployee and ContractEmployee classes. Now Let us create Java classes for the above hierarchy to implement
 

Model class

 
File: Employee.java

package model;

public class Employee {
	private int empID;
	private String empName;

	public int getEmpID() {
		return empID;
	}

	public String getEmpName() {
		return empName;
	}

	public void setEmpID(int empID) {
		this.empID = empID;
	}

	public void setEmpName(String empName) {
		this.empName = empName;
	}

}

 
File: PermanentEmployee.java

package model;

public class PermanentEmployee extends Employee {
	private String companyName;

	public String getCompanyName() {
		return companyName;
	}

	public void setCompanyName(String companyName) {
		this.companyName = companyName;
	}

}

 
File: ContractEmployee.java

package model;

public class ContractEmployee extends Employee {
	String contractorName;

	public String getContractorName() {
		return contractorName;
	}

	public void setContractorName(String contractorName) {
		this.contractorName = contractorName;
	}
}

 

Hibernate Mapping xml

 

<hibernate-mapping>
	<class name="model.Employee" table="EMPLOYEE">
		<id name="empID" type="int" column="EMPID">
			<generator class="assigned" />
		</id>
		<property name="empName" type="java.lang.String" column="EMP_NAME" />

		<joined-subclass name="model.PermanentEmployee"
			table="P_EMPLOYEE" dynamic-update="true">
			<key column="PID" />
			<property name="companyName" column="COMPANY_NAME" />
		</joined-subclass>

		<joined-subclass name="model.ContractEmployee"
			table="T_EMPLOYEE" dynamic-update="true">
			<key column="TID" />
			<property name="contractorName" column="CONTRACTOR_NAME" />
		</joined-subclass>

	</class>
</hibernate-mapping>

 
In case of table per subclass class, there will be three tables in the database, each representing a particular class.
 
The joined-subclass sub element of class, specifies the subclass. The key sub element of joined-subclass is used to generate the foreign key in the subclass mapped table. This foreign key will be associated with the primary key of parent class mapped table.
 

Hibernate Configuration file

 

<hibernate-configuration>

	<session-factory>
		<!-- Database connection settings -->
		<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
		<property name="hibernate.connection.username">system</property>
		<property name="hibernate.connection.password">admin</property>
		<property name="hibernate.connection.url">jdbc:oracle:thin:@127.0.0.1:1521:XE</property>

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

		<!-- SQL dialect -->
		<property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>

		<!-- Enable Hibernate's current session context -->
		<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 sysout -->
		<property name="show_sql">true</property>

		<!-- Drop and re-create the database schema on startup -->
		<property name="hibernate.hbm2ddl.auto">create</property>
		<mapping resource="Employee.hbm.xml" />

	</session-factory>

</hibernate-configuration>

 
The hbm2ddl.auto property is defined for creating automatic table in the database.
 

Client program

 
Now let us write one client program for three bean programs – Employee, PermanentEmployee, ContractEmployee
 

package util;

import model.ContractEmployee;
import model.PermanentEmployee;

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

public class HibernateUtil {

	public static void main(String[] args) {

		Configuration cf = new Configuration().configure("hibernate.cfg.xml");

		StandardServiceRegistryBuilder srb = new StandardServiceRegistryBuilder();
		srb.applySettings(cf.getProperties());
		ServiceRegistry sr = srb.build();
		SessionFactory sf = cf.buildSessionFactory(sr);

		Session session = sf.openSession();

		PermanentEmployee p1 = new PermanentEmployee();
		p1.setEmpID(1);
		p1.setEmpName("Ameer");
		p1.setCompanyName("CTS");

		PermanentEmployee p2 = new PermanentEmployee();
		p2.setEmpID(2);
		p2.setEmpName("Lourde");
		p2.setCompanyName("TCS");

		// create two objects of ContractEmployee
		ContractEmployee t1 = new ContractEmployee();
		t1.setEmpID(3);
		t1.setEmpName("Prabhu");
		t1.setContractorName("ABD Consultancy");

		ContractEmployee t2 = new ContractEmployee();
		t2.setEmpID(4);
		t2.setEmpName("Badru");
		t2.setContractorName("MN Consultancy");

		Transaction tx = session.beginTransaction();

		session.save(p1);
		session.save(p2);
		session.save(t1);
		session.save(t2);

		tx.commit();
		System.out.println("Object saved successfully !");
		session.close();
		sf.close();
	}
}

 

Eclipse Console

 
Table per sub class

Database output

 
Employee
 
P_EMPLOYEE
 
T_Employee
 
PID and TID are the foreign keys for EMPID of super class.

Read More