Hibernate Basics
Hibernate Basics
What is Hibernate ?
In the hibernate u need not bother about how to create table in SQL and u need not
to remember connection, prepared statement like that data is stored in persistence
way in data base. It makes developer life easy
Hibernate Architecture :
Hibernate:
1) Itself opens connection to database,
2) Converts HQL (Hibernate Query Language) statements to database
specific statement,
3) Receives result set,
4) Then performs mapping of these database specific data to Java objects
which are directly used by Java application.
Hibernate
Hibernate communication with RDBMS :
Example,
Retrieve list of employees from Employee table using Hibernate.
/* Load the hibernate configuration file */
Configuration cfg = new Configuration();
cfg.configure(CONFIG_FILE_LOCATION);
/* Create the session factory */
SessionFactory sessionFactory = cfg.buildSessionFactory();
Hibernate
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.mf.bean.EmployeeBean" table="t_employee">
<id name="id" type="string" unsaved-value="null">
<column name="id" sql-type="varchar(32)" not-null="true"/>
<generator class="uuid"/>
</id>
<property name="name">
<column name="name" />
</property>
<property name="salary">
<column name="salary" />
</property>
</class>
</hibernate-mapping>
2) Transparent Persistence
The automatic mapping of Java objects with database tables and vice versa is
called Transparent Persistence.
Hibernate provides transparent persistence and developer does not
need to write code explicitly to map database tables tuples to
application objects during interaction with RDBMS.
Hibernate
5) Maintenance Cost
With JDBC, it is developers responsibility to handle JDBC result set and convert it
to Java objects through code to use this persistent data in application.
So with JDBC, mapping between Java objects and database tables is
done manually.
Hibernate reduces lines of code by maintaining object-table mapping itself and
returns result to application in form of Java objects.
It relieves programmer from manual handling of persistent data,
hence reducing the development time and maintenance cost.
Disadvantages of Hibernate :
Hibernate
Hibernate vs JDBC :
Hibernate
Hibernate
JDBC
is
in
case
Hibernate
then
hibernate
and
2nd
level.
So
you
can
doest
Not
provide
any
you
don't
need
to
write
queries.
No need to create any connection pool in In case of JDBC you need to write your
case
of
Hibernate.
You
can
c3p0.
In the XML file you can see all the
relations between tables in case of
Hibernate
Hibernate. Easy readability.
You can load your objects on start up JDBC Don't have such support.
using
lazy=false
in
case
of
Hibernate.
Hibernate Supports automatic versioning JDBC Does Not Support it.
of rows
Advantages of hibernates:
1.Hibernate supports Inheritance, Associations, Collections
2.In hibernate if we save the derived class object, then its base class object will also be
stored into the database, it means hibernate supporting inheritance
3. Hibernate supports relationships like One-To-Many, One-To-One,
Many-To-Many, Many-To-One
4. This will also supports collections like List, Set, Map (Only new
collections)
5. In JDBC all exceptions are checked exceptions, so we must write code in try,
catch and throws, but in hibernate we only have Unchecked exceptions, so no need
to write try, catch, or no need to write throws. Actually in hibernate we
have the translator which converts checked to Unchecked
6. Hibernate has capability to generate primary keys automatically while we are
storing the records into database
7. Hibernate has its own query language, i.e hibernate query language which
is database independent So if we change the database, then also our
application will works as HQL is database independent
8. HQL contains database independent commands While we are inserting any
record, if we dont have any particular table in the database, JDBC will
rises an error like View not exist, and throws exception, but in case
of hibernate, if it not found any table in the database this will create the table for us.
9. Hibernate supports caching mechanism by this, the number of round trips
between an application and the database will be reduced, by using this
caching technique an application performance will be increased automatically.
10. Hibernate supports annotations, apart from XML
11. Hibernate provided Dialect classes, so we no need to write SQL queries in
hibernate, instead we use the methods provided by that API.
12. Getting pagination in hibernate is quite simple.
Hibernate
13. Hibernate takes care of mapping Java classes to database tables using XML files
and without writing any line of code.
14. Provides simple APIs for storing and retrieving Java objects directly to
and from the database.
15. If there is change in Database or in any table then the only need to change XML file
properties.
16. Provides Simple querying of data.
What is Hibernate ?
Hibernate maps Java classes to database tables and from Java data types to SQL
data types.
Supported Databases:
Hibernate supports almost all the major RDBMS. Following is list of few
of the database engines supported by Hibernate.
Hibernate
Supported Technologies:
Hibernate supports
following:
variety
of
other
technologies,
including
the
XDoclet Spring
J2EE
Eclipse plug-ins
Maven
Detailed View
Hibernate uses various existing Java APIs, like JDBC, Java Transaction
API(JTA), and Java Naming and Directory Interface (JNDI).
Configuration Object:
Hibernate
Java classes and database tables.
SessionFactory Object:
The SessionFactory is a thread safe object and used by all the threads
of an application.
You would need one SessionFactory object per database using a separate
configuration file.
So if you are using multiple databases then you would have to create
multiple SessionFactory objects.
Session Object:
Persistent
object.
The session objects should not be kept open for a long time because they are
not usually thread safe and they should be created and destroyed them as
needed.
objects
are
saved
and
retrieved
through
Session
Transaction Object:
A Transaction represents a unit of work with the database and most of the
RDBMS supports transaction functionality.
Query Object:
Hibernate
Criteria Object:
Criteria object are used to create and execute object oriented criteria
queries to retrieve objects.
Hibernate Properties:
To configure for a databases in a standalone situation
Properties
Description
hibernate.dialect
hibernate.connection.driver_class
hibernate.connection.url
hibernate.connection.username
hibernate.connection.password
hibernate.connection.pool_size
hibernate.connection.autocommit
The database along with an application server and JNDI then you would
have to configure the following properties
Properties
Description
hibernate.connection.datasource
hibernate.jndi.class
hibernate.jndi.<JNDIpropertyname>
hibernate.jndi.url
hibernate.connection.username
hibernate.connection.password
Example hibernate.cfg.xml,
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
Hibernate
<session-factory>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- Assume test is the database name -->
<property name="hibernate.connection.url">
jdbc:mysql://localhost/test
</property>
<property name="hibernate.connection.username">
root
</property>
<property name="hibernate.connection.password">
root123
</property>
<!-- List of XML mapping files -->
<mapping resource="Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
The above configuration file includes <mapping> tags which are related to
hibernate-mapping file
Hibernate Sessions :
Transient State :
When it is just created and has no primary key, the state is called
transient.
If Object is transient, instance has just been instantiated with
Hibernate
Example,
Car car = new Car();
car.setName(BMW);
Persistent State :
When the session is opened and the object is just saved in or retrieved from the
database. This state is called persistent.
During this state Hibernate manages the object and saves your
changes, if you commit them.
Below you can see an example. A car is saved and the name is
changed afterwards. As the car is in persistent state, the new name
will be saved.
Detached State :
When the session was closed, the state changes to detached. The object
is detached from its session.
Hibernate
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// do some work
...
tx.commit();
}
catch (Exception e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
If the Session throws an exception, the transaction must be rolled back
and the session must be discarded.
All classes that do not extend or implement some specialized classes and
interfaces required by the EJB framework.
Sample POJO,
public class Employee {
private int id;
private String firstName;
private String lastName;
private int salary;
Default constructor, Id
& private declaration,
public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
Hibernate
This mapping file instructs Hibernate how to map the defined class
or classes to the database tables.
Middlegen
AndroMDA.
Example,
public class Employee {
private int id;
private String firstName;
private String lastName;
private int salary;
public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
Hibernate
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}
There would be one table corresponding to each object you are willing to
provide persistence. Consider above objects need to be stored and
retrieved into the following RDBMS table:
create table EMPLOYEE (
id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary
INT default NULL,
PRIMARY KEY (id)
);
Based on the two above entities we can define following mapping file
which instructs Hibernate how to map the defined class or classes to the
database tables.
Root
element
<hibernate-mapping>
DB table name
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
Automatic
</meta>
Table primary key
Primary
<id name="id" type="int" column="id">
Key
<generator class="native"/>
generator
Table column
</id>
Java datatype
Converts to
SQL datatype
Hibernate
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
Pojo
<property name="salary" column="salary" type="int"/>
property
</class>
</hibernate-mapping>
Hibernate type
You should save
<classname>.hbm.xml.
the
mapping
document
in
file
with
the
format
The <class> elements are used to define specific mappings from a Java
classes to the database tables. The Java class name is specified
using the name attribute of the class element and the database
table name is specified using the table attribute.
The <meta> element is optional element and can be used to create the
class description.
The
<generator>
element within
the id
element is
used to
automatically generate the primary key values. Set the class
attribute of the generator element is set to native to let hibernate
pick up either identity, sequence or hilo algorithm to create primary
key depending upon the capabilities of the underlying database.
Hibernate
save()
persist()
saveOrUpdate()
merge()
delete()
get()
load()
update()
lock()
replicate()
persistent
by
calling
update(),
be
made
org.hibernate.HibernateException;
org.hibernate.Session;
org.hibernate.Transaction;
org.hibernate.SessionFactory;
org.hibernate.cfg.Configuration;
Hibernate
Integer empID3 = ME.addEmployee("John", "Paul", 10000);
/* List down all the employees */
ME.listEmployees();
/* Update employee's records */
ME.updateEmployee(empID1, 5000);
/* Delete an employee from the database */
ME.deleteEmployee(empID2);
/* List down new list of the employees */
ME.listEmployees();
}
/* Method to CREATE an employee in the database */
public Integer addEmployee(String fname, String lname, int salary){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}
/* Method to READ all the employees */
public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator =
employees.iterator(); iterator.hasNext();){
Employee employee = (Employee) iterator.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
Hibernate
/* Method to UPDATE salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to DELETE an employee from the records */
public void deleteEmployee(Integer EmployeeID){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
session.delete(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}
Hibernate
can
persist
instances
of
java.util.Map, java.util.Set,
java.util.SortedMap, java.util.SortedSet, java.util.List,
and
any
array
of
persistent entities or values.
Collection type
java.util.Set
Hibernate
java.util.SortedSet
java.util.List
java.util.Collection
java.util.Map
java.util.SortedMap
Association Mappings:
classes
and
the
Mapping type
Description
Many-to-One
One-to-One
One-to-Many
Many-to-Many
Component Mappings:
If the referred class does not have it's own life cycle and completely
depends on the life cycle of the owning entity class, then the referred class
is called as the Component class.
Mapping type
Description
Component Mappings
Hibernate
Hibernate Using Set in Mapping Files : (java.util.Set)
It does not require index element not index based contains only
unique values
You can use Set collection in your class when there is no duplicate
element required in the collection.
Example,
create table EMPLOYEE (
id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary
INT default NULL,
PRIMARY KEY (id)
);
create table CERTIFICATE (
id INT NOT NULL auto_increment,
certificate_name VARCHAR(30) default NULL,
employee_id INT default NULL,
PRIMARY KEY (id)
);
There will be one-to-many relationship between EMPLOYEE and CERTIFICATE
objects
import java.util.*;
public class Employee {
private int id;
private String firstName;
private String lastName;
private int salary;
private Set certificates;
public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
getter ...
setter ...
Hibernate
public Certificate() {}
public Certificate(String name) {
this.name = name;
}
getter ...
setter ...
public boolean equals(Object obj) {
if (obj == null) return false;
if (!this.getClass().equals(obj.getClass())) return false;
Certificate obj2 = (Certificate)obj;
if((this.id == obj2.getId()) && (this.name.equals(obj2.getName())))
{
return true;
}
return false;
}
public int hashCode() {
int tmp = 0;
tmp = ( id + name ).hashCode();
return tmp;
}
}
Hibernate
<set name="certificates" cascade="all" table=certiticate>
<key column="employee_id"/>
<one-to-many class="Certificate"/>
<element column=answer type=string></element>
</set>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>
<class name="Certificate" table="CERTIFICATE">
<meta attribute="class-description">
This class contains the certificate records.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="name" column="certificate_name" type="string"/>
</class>
</hibernate-mapping>
The <set> element is new here and has been introduced to set the
relationship between Certificate and Employee classes.
The name attribute is set to the defined Set variable in the parent
class, in our case it is certificates.
For each set variable, we need to define a separate set element in the
mapping file.
The <key> element is the column in the CERTIFICATE table that holds
the foreign key to the parent object ie. table EMPLOYEE.
Hibernate
If we use natural ordering then its iterator will traverse the set in
ascending element order.
Example,
Same Table Employee and Certificate which has been used the above
scenario.
import java.util.*;
public class Employee {
private int id;
private String firstName;
private String lastName;
private int salary;
private SortedSet certificates;
public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
getters ...
setters ...
Hibernate
} else if(thatCertificate == null) {
return BEFORE;
} else {
return thisCertificate.compareTo(thatCertificate);
}
}
Hibernate
But we are using a custom comparator class MyClass in our mapping file so
we would have to create this class based on our sorting algorithm. Let us
do descending sorting in this class using this class.
import java.util.Comparator;
public class MyClass implements Comparator<Certificate>{
public int compare(Certificate o1, Certificate o2) {
final int BEFORE = -1;
final int AFTER = 1;
/* To reverse the sorting order, multiple by -1 */
if (o2 == null) {
return BEFORE * -1;
}
Comparable thisCertificate = o1.getName();
Comparable thatCertificate = o2.getName();
if(thisCertificate == null) {
return AFTER * 1;
} else if(thatCertificate == null) {
return BEFORE * -1;
} else {
return thisCertificate.compareTo(thatCertificate) * -1;
}
}}
Using List :
The user can access elements by their integer index, and search for
elements in the list.
import java.util.*;
public class Employee {
private int id;
private String firstName;
private String lastName;
private int salary;
private List certificates;
public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
Hibernate
this.salary = salary;
}
getters and setters ...
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
One-to-many tag is used
<meta attribute="class-description">
Inside <list> to store
This class contains the employee detail.
</meta>
Entity reference in list
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
element tag is used
<list name="certificates" cascade="all" table=employee>
If stores string values in
<key
column="employee_id"/>
Collection instead of
Index of the element
<list-index column="idx"/>
Entity reference
Inside <list>
<one-to-many class="Certificate"/>
<element column=answer type=string></element>
</list>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>
<class name="Certificate" table="CERTIFICATE">
<meta attribute="class-description">
This class contains the certificate records.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="name" column="certificate_name" type="string"/>
</class>
</hibernate-mapping>
The <list-index> element is used to keep the position of the element and map
with the index column in the collection table.
The index of the persistent list starts at zero. You could change this,
for example, with <list-index base="1".../> in your mapping.
A Bag is a java collection that stores elements without caring about the
sequencing but allow duplicate elements in the list.
Hibernate
Its not index based and does not contain any index column
Example,
import java.util.*;
public class Employee {
private int id;
private String firstName;
private String lastName;
private int salary;
private Collection certificates;
public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
getters and setters ...
Hibernate
</id>
<property name="name" column="certificate_name" type="string"/>
</class>
</hibernate-mapping>
set
the
relationship
between
Example,
import java.util.*;
public class Employee {
private int id;
private String firstName;
private String lastName;
private int salary;
private Map certificates;
public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
getters and setters ...
Hibernate
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
Key part in Map
</id>
element tag is used
<map name="certificates" cascade="all" table=employee>
If stores string values in
<key column="employee_id"/>
One-to-many tag is
Collection instead of
<index
column="certificate_type"
type="string"/>
Used Inside <map>
Entity reference here
<one-to-many class="Certificate"/>
Is <element> is value
part
<element column=answer type=string></element>
</map>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>
<class name="Certificate" table="CERTIFICATE">
<meta attribute="class-description">
This class contains the certificate records.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="name" column="certificate_name" type="string"/>
</class>
</hibernate-mapping>
The <index> element is used to represents the key parts of the key/value map pair. The key
will be stored in the column certificate_type using a type of string.
Using SortedMap (java.util.SortedMap):
Duplicate elements are not allowed in the map. The map is ordered
according to the natural ordering of its keys, or by a Comparator
typically provided at sorted map creation time.
import java.util.*;
public class Employee {
private int id;
private String firstName;
private String lastName;
private int salary;
private SortedMap certificates;
Hibernate
public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
setters and getters ...
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
Same sort concepts
<id name="id" type="int" column="id">
Used in above
<generator class="native"/>
SortedSet Scenario
</id>
<map name="certificates" cascade="all" sort="MyClass" table=employee>
<key column="employee_id"/>
<index column="certificate_type" type="string"/>
<one-to-many class="Certificate"/>
One-to-many tag is used
Inside <map>
</map>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>
<class name="Certificate" table="CERTIFICATE">
<meta attribute="class-description">
This class contains the certificate records.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="name" column="certificate_name" type="string"/>
</class>
</hibernate-mapping>
One-to-many Examples with Collection Mappings
Hibernate
Table Creation
CREATE TABLE `department` (
`department_id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`dept_name` VARCHAR(50) NOT NULL DEFAULT '0',
PRIMARY KEY (`department_id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
AUTO_INCREMENT=115
CREATE TABLE `employee` (
`employee_id` BIGINT(10) NOT NULL AUTO_INCREMENT,
`firstname` VARCHAR(50) NULL DEFAULT NULL,
`lastname` VARCHAR(50) NULL DEFAULT NULL,
`birth_date` DATE NULL DEFAULT NULL,
`cell_phone` VARCHAR(15) NULL DEFAULT NULL,
`department_id` BIGINT(20) NULL DEFAULT NULL,
PRIMARY KEY (`employee_id`),
INDEX `FK_DEPT` (`department_id`),
CONSTRAINT `FK_DEPT` FOREIGN KEY (`department_id`) REFERENCES
`department` (`department_id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
Hibernate
private Set<Employee> employees;
// Getter and Setter methods
}
Employee :
public class Employee {
private Long employeeId;
private String firstname;
private String lastname;
private Date birthDate;
private String cellphone;
private Department department;
public Employee() {
}
public Employee(String firstname, String lastname, Date birthdate,
String phone) {
this.firstname = firstname;
this.lastname = lastname;
this.birthDate = birthdate;
this.cellphone = phone;
}
// Getter and Setter methods
}
Hibernate Utill
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
Hibernate
public class HibernateUtil {
private static final SessionFactory sessionFactory =
buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Employee hbm file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="net.viralpatel.hibernate">
<class name="Employee" table="EMPLOYEE">
<id name="employeeId" column="EMPLOYEE_ID">
<generator class="native" />
</id>
<property name="firstname" />
<property name="lastname" column="lastname" />
<property name="birthDate" type="date" column="birth_date" />
<property name="cellphone" column="cell_phone" />
<many-to-one name="department"
class="net.viralpatel.hibernate.Department" fetch="select">
Hibernate
<column name="department_id" not-null="true" />
</many-to-one>
</class>
</hibernate-mapping>
Department hbm file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="net.viralpatel.hibernate">
<class name="Department" table="DEPARTMENT">
<id name="departmentId" type="java.lang.Long"
column="DEPARTMENT_ID" >
<generator class="native" />
</id>
<property name="departmentName" column="DEPT_NAME"/>
<set name="employees" table="employee"
inverse="true" lazy="true" fetch="select">
<key>
<column name="department_id" not-null="true" />
</key>
<one-to-many class="net.viralpatel.hibernate.Employee" />
</set>
</class>
</hibernate-mapping>
Execute <set> example
import org.hibernate.Session;
import org.hibernate.SessionFactory;
public class Main {
Hibernate
public static void main(String[] args) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
Department department = new Department();
department.setDepartmentName("Sales");
session.save(department);
Employee emp1 = new Employee("Nina", "Mayers", "1212");
Employee emp2 = new Employee("Tony", "Almeida", "4343");
emp1.setDepartment(department);
emp2.setDepartment(department);
session.save(emp1);
session.save(emp2);
session.getTransaction().commit();
session.close();
}
}
Output
Hibernate: insert into DEPARTMENT (DEPT_NAME) values (?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date,
cell_phone, department_id) values (?, ?, ?, ?, ?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date,
cell_phone, department_id) values (?, ?, ?, ?, ?)
One-to-Many <bag> example
A <bag> is an unordered collection, which can contain duplicated elements. That means if you persist a bag
with some order of elements, you cannot expect the same order retains when the collection is retrieved.
There is not a bag concept in Java collections framework, so we just use a java.util.List
correspond to a <bag>.
To implement Bag in our one-to-many mapping example, we will do following changes:
Department
Hibernate
import java.util.ArrayList;
import java.util.List;
public class Department {
private Long departmentId;
private String departmentName;
private List<Employee> employees;
// Getter and Setter methods
}
Department hbm file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="net.viralpatel.hibernate">
<class name="Department" table="DEPARTMENT">
<id name="departmentId" type="java.lang.Long"
column="DEPARTMENT_ID" >
<generator class="native" />
</id>
<property name="departmentName" column="DEPT_NAME"/>
<bag name="employees" table="employee"
inverse="true" lazy="true" fetch="select">
<key>
<column name="employee_id" not-null="true" />
</key>
<one-to-many class="net.viralpatel.hibernate.Employee" />
</bag>
Hibernate
</class>
</hibernate-mapping>
output
Hibernate: insert into DEPARTMENT (DEPT_NAME) values (?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date,
cell_phone, department_id) values (?, ?, ?, ?, ?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date,
cell_phone, department_id) values (?, ?, ?, ?, ?)
One-to-Many <list> example
A <list> is an indexed collection where the index will also be persisted. That means we can retain the order
of the list when it is retrieved. It differs from <bag> for it persists the element Index while a <bag> does not.
The corresponding type of a <list> in Java is java.util.List.
To implement List in our one-to-many mapping example, we will do following changes:
8.1 Add Index Column in Employee Table
DROP TABLE if exists `employee`;
CREATE TABLE `employee` (
`employee_id` BIGINT(10) NOT NULL AUTO_INCREMENT,
`firstname` VARCHAR(50) NULL DEFAULT NULL,
`lastname` VARCHAR(50) NULL DEFAULT NULL,
`birth_date` DATE NULL DEFAULT NULL,
`cell_phone` VARCHAR(15) NULL DEFAULT NULL,
`department_id` BIGINT(20) NULL DEFAULT NULL,
`idx` INT(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`employee_id`),
INDEX `FK_DEPT` (`department_id`),
CONSTRAINT `FK_DEPT` FOREIGN KEY (`department_id`) REFERENCES `department`
(`department_id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
Department
import java.util.List;
public class Department {
private Long departmentId;
Hibernate
private String departmentName;
private List<Employee> employees;
// Getter and Setter methods
}
Department hbm file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="net.viralpatel.hibernate">
<class name="Department" table="DEPARTMENT">
<id name="departmentId" type="java.lang.Long" column="DEPARTMENT_ID">
<generator class="native" />
</id>
<property name="departmentName" column="DEPT_NAME"/>
<list name="employees" table="employee" inverse="false" cascade="all">
<key column="department_id" />
<list-index column="idx" />
<one-to-many class="net.viralpatel.hibernate.Employee" />
</list>
</class>
</hibernate-mapping>
output
Hibernate: insert into DEPARTMENT (DEPT_NAME) values (?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone) values (?, ?, ?, ?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone) values (?, ?, ?, ?)
Hibernate: update EMPLOYEE set department_id=?, idx=? where EMPLOYEE_ID=?
Hibernate: update EMPLOYEE set department_id=?, idx=? where EMPLOYEE_ID=?
Hibernate
Hibernate
<property name="departmentName" column="DEPT_NAME"/>
<array name="employees" table="employee" inverse="false" cascade="all">
<key column="department_id" />
<list-index column="idx" />
<one-to-many class="net.viralpatel.hibernate.Employee" />
</array>
</class>
</hibernate-mapping>
Output
Hibernate: insert into DEPARTMENT (DEPT_NAME) values (?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone) values (?, ?, ?, ?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone) values (?, ?, ?, ?)
Hibernate: update EMPLOYEE set department_id=?, idx=? where EMPLOYEE_ID=?
Hibernate: update EMPLOYEE set department_id=?, idx=? where EMPLOYEE_ID=?
Association :
Many-to-One :
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
Seperate tag
Is used here
Hibernate
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
<many-to-one name="address" column="address" class="Address" not-null="true"/>
</class>
Many-to-One
Relationships
Hibernate
</class>
Set unique
Constraint to make
The one-to-one mapping
Hibernate
One-to-one
Relationship
</hibernate-mapping>
One-to-Many :
A One-to-Many mapping can be implemented using a Set java collection
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<set name="certificates" cascade="all" table=employee>
<key column="employee_id"/>
One-to-many tag is used
Inside <set>
<one-to-many class="Certificate"/>
</set>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>
<class name="Certificate" table="CERTIFICATE">
<meta attribute="class-description">
This class contains the certificate records.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="name" column="certificate_name" type="string"/>
</class>
</hibernate-mapping>
Many-to-Many :
A Many-to-Many mapping can be implemented using a Set java collection
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
Hibernate
<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
Table is used
<id name="id" type="int" column="id">
To display
<generator class="native"/>
All records
</id>
<set name="certificates" cascade="save-update" table="EMP_CERT"> Many-to-many tag
<key column="employee_id"/>
Is used inside
<set>
<many-to-many column="certificate_id" class="Certificate"/>
</set>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>
<class name="Certificate" table="CERTIFICATE">
<meta attribute="class-description">
This class contains the certificate records.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="name" column="certificate_name" type="string"/>
</class>
</hibernate-mapping>
/* EMPLOYEEDETAIL table */
CREATE TABLE `employeedetail` (
`employee_id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`street` VARCHAR(50) NULL DEFAULT NULL,
`city` VARCHAR(50) NULL DEFAULT NULL,
`state` VARCHAR(50) NULL DEFAULT NULL,
Hibernate
`country` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`employee_id`),
CONSTRAINT `FKEMPL` FOREIGN KEY (`employee_id`) REFERENCES `employee`
(`employee_id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
AUTO_INCREMENT=216
public class Employee {
private
private
private
private
private
private
Long employeeId;
String firstname;
String lastname;
Date birthDate;
String cellphone;
EmployeeDetail employeeDetail;
public Employee() {
}
public Employee(String firstname, String lastname, Date birthdate,
String phone) {
this.firstname = firstname;
this.lastname = lastname;
this.birthDate = birthdate;
this.cellphone = phone;
}
Long employeeId;
String street;
String city;
String state;
String country;
Hibernate
// Getter and Setter methods
}
Note that in above model classes, employeeId is common. This is the primary key of Employee table
that exhibits One-to-one relationship with EmployeeDetail table.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="net.viralpatel.hibernate">
<class name="Employee" table="EMPLOYEE">
<id name="employeeId" column="EMPLOYEE_ID">
<generator class="native" />
</id>
<one-to-one name="employeeDetail"
class="net.viralpatel.hibernate.EmployeeDetail"
cascade="save-update"></one-to-one>
<property
<property
<property
<property
name="firstname" />
name="lastname" column="lastname" />
name="birthDate" type="date" column="birth_date" />
name="cellphone" column="cell_phone" />
</class>
<class name="EmployeeDetail" table="EMPLOYEEDETAIL">
<id name="employeeId" type="java.lang.Long">
<column name="EMPLOYEE_ID" />
<generator class="foreign">
<param name="property">employee</param>
</generator>
</id>
<one-to-one name="employee" class="net.viralpatel.hibernate.Employee"
constrained="true"></one-to-one>
<property
<property
<property
<property
</class>
name="street" column="STREET"/>
name="city" column="CITY"/>
name="state" column="STATE"/>
name="country" column="COUNTRY"/>
</hibernate-mapping>
Hibernate
<hibernate-configuration>
<session-factory>
<property
name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property
name="connection.url">jdbc:mysql://localhost:3306/tutorial</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">validate</property>
<mapping resource="net/viralpatel/hibernate/EmployeeDetail.hbm.xml"/>
<mapping resource="net/viralpatel/hibernate/Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
ex);
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
public class Main {
public static void main(String[] args) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
Hibernate
EmployeeDetail employeeDetail = new EmployeeDetail("10th Street",
"LA", "San Francisco", "U.S.");
Employee employee = new Employee("Nina", "Mayers", new Date(121212),
"114-857-965");
employee.setEmployeeDetail(employeeDetail);
employeeDetail.setEmployee(employee);
session.save(employee);
Output
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone)
values (?, ?, ?, ?)
Hibernate: insert into EMPLOYEEDETAIL (STREET, CITY, STATE, COUNTRY,
EMPLOYEE_ID) values (?, ?, ?, ?, ?)
Hibernate: select employee0_.EMPLOYEE_ID as EMPLOYEE1_1_, employee0_.firstname
as firstname1_, employee0_.lastname as lastname1_, employee0_.birth_date as
birth4_1_, employee0_.cell_phone as cell5_1_ from EMPLOYEE employee0_
Hibernate: select employeede0_.EMPLOYEE_ID as EMPLOYEE1_0_0_,
employeede0_.STREET as STREET0_0_, employeede0_.CITY as CITY0_0_,
employeede0_.STATE as STATE0_0_, employeede0_.COUNTRY as COUNTRY0_0_ from
EMPLOYEEDETAIL employeede0_ where employeede0_.EMPLOYEE_ID=?
Nina , Mayers, San Francisco
javax.persistence.CascadeType;
javax.persistence.Column;
javax.persistence.Entity;
javax.persistence.GeneratedValue;
javax.persistence.Id;
javax.persistence.OneToOne;
javax.persistence.Table;
Hibernate
@Entity
@Table(name="EMPLOYEE")
public class Employee {
@Id
@GeneratedValue
@Column(name="employee_id")
private Long employeeId;
@Column(name="firstname")
private String firstname;
@Column(name="lastname")
private String lastname;
@Column(name="birth_date")
private Date birthDate;
@Column(name="cell_phone")
private String cellphone;
@OneToOne(mappedBy="employee", cascade=CascadeType.ALL)
private EmployeeDetail employeeDetail;
public Employee() {
}
public Employee(String firstname, String lastname, Date birthdate, String
phone) {
this.firstname = firstname;
this.lastname = lastname;
this.birthDate = birthdate;
this.cellphone = phone;
}
import
import
import
import
import
import
import
javax.persistence.Column;
javax.persistence.Entity;
javax.persistence.GeneratedValue;
javax.persistence.Id;
javax.persistence.OneToOne;
javax.persistence.PrimaryKeyJoinColumn;
javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
@Entity
@Table(name="EMPLOYEEDETAIL")
public class EmployeeDetail {
@Id
Hibernate
@Column(name="employee_id", unique=true, nullable=false)
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign",
parameters=@Parameter(name="property", value="employee"))
private Long employeeId;
@Column(name="street")
private String street;
@Column(name="city")
private String city;
@Column(name="state")
private String state;
@Column(name="country")
private String country;
@OneToOne
@PrimaryKeyJoinColumn
private Employee employee;
public EmployeeDetail() {
}
public EmployeeDetail(String street, String city, String state, String
country) {
this.street = street;
this.city = city;
this.state = state;
this.country = country;
}
// Getter and Setter methods
}
Note that in EmployeeDetail class we have used @GenericGenerator to specify primary key. This
will ensure that the primary key from Employee table is used instead of generating a new one.
Hibernate-configuration file
Instead of <mapping resource = hbm file location> using the following tag rest of all same as above
<mapping class="net.viralpatel.hibernate.EmployeeDetail"/>
<mapping class="net.viralpatel.hibernate.Employee"/>
Hibernate Utill
Instead of Configuration here using the AnnotationConfiguration class to create configuration object
return new AnnotationConfiguration().configure().buildSessionFactory();
Hibernate
@Entity
@Table(name="EMPLOYEE")
public class Employee {
@Id
@GeneratedValue
@Column(name="employee_id")
private Long employeeId;
@Column(name="firstname")
private String firstname;
@Column(name="lastname")
private String lastname;
@Column(name="birth_date")
private Date birthDate;
@Column(name="cell_phone")
private String cellphone;
@ManyToOne
@JoinColumn(name="department_id")
private Department department;
public Employee() {
}
public Employee(String firstname, String lastname, String phone) {
this.firstname = firstname;
this.lastname = lastname;
this.birthDate = new Date(System.currentTimeMillis());
this.cellphone = phone;
}
@Entity
@Table(name="DEPARTMENT")
public class Department {
@Id
Hibernate
@GeneratedValue
@Column(name="DEPARTMENT_ID")
private Long departmentId;
@Column(name="DEPT_NAME")
private String departmentName;
@OneToMany(mappedBy="department")
private Set<Employee> employees;
mappedBy refers to the property name of the association on the owner side. In our case, this is
passport. As you can see, you dont have to (must not) declare the join column since it has already
been declared on the owners side.
Implemented Class
public class Main {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
Department department = new Department();
department.setDepartmentName("Sales");
session.save(department);
Employee emp1 = new Employee("Nina", "Mayers", "111");
Employee emp2 = new Employee("Tony", "Almeida", "222");
emp1.setDepartment(department);
emp2.setDepartment(department);
session.save(emp1);
session.save(emp2);
session.getTransaction().commit();
session.close();
Output
Hibernate: insert into DEPARTMENT (DEPT_NAME) values (?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone,
department_id) values (?, ?, ?, ?, ?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone,
department_id) values (?, ?, ?, ?, ?)
Hibernate
One- To Many Bi-directional Indexed mapping
CREATE TABLE `employee` (
`employee_id` BIGINT(10) NOT NULL AUTO_INCREMENT,
`firstname` VARCHAR(50) NULL DEFAULT NULL,
`lastname` VARCHAR(50) NULL DEFAULT NULL,
`birth_date` DATE NULL DEFAULT NULL,
`cell_phone` VARCHAR(15) NULL DEFAULT NULL,
`department_id` BIGINT(20) NULL DEFAULT NULL,
`idx` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`employee_id`),
INDEX `FK_DEPT` (`department_id`),
CONSTRAINT `FK_DEPT` FOREIGN KEY (`department_id`) REFERENCES `department`
(`department_id`)
)
@Entity
@Table(name="DEPARTMENT")
public class Department {
@Id
@GeneratedValue
@Column(name="DEPARTMENT_ID")
private Long departmentId;
@Column(name="DEPT_NAME")
private String departmentName;
@OneToMany(cascade={CascadeType.ALL})
@JoinColumn(name="department_id")
@IndexColumn(name="idx")
private List<Employee> employees;
// Getter and Setter methods
}
Note that in Department entity class, we removed mappedBy clause from @OneToMany. This mark
Department as the relationship owner and make it responsible to update foreign keys and index values.
Also we specified index column using @IndexColumn annotation to specify which column in Employee table
we would like to store index in.
@Entity
@Table(name="EMPLOYEE")
public class Employee {
@Id
@GeneratedValue
@Column(name="employee_id")
private Long employeeId;
@Column(name="firstname")
Hibernate
private String firstname;
@Column(name="lastname")
private String lastname;
@Column(name="birth_date")
private Date birthDate;
@Column(name="cell_phone")
private String cellphone;
@ManyToOne
@JoinColumn(name="department_id",
Foreign Key
insertable=false, updatable=false,
nullable=false)
private Department department;
public Employee() {
}
public Employee(String firstname, String lastname, String phone) {
this.firstname = firstname;
this.lastname = lastname;
this.birthDate = new Date(System.currentTimeMillis());
this.cellphone = phone;
}
Hibernate
Output
Hibernate: insert into DEPARTMENT (DEPT_NAME) values (?)
Hibernate: insert into EMPLOYEE (birth_date, cell_phone, firstname, lastname)
values (?, ?, ?, ?)
Hibernate: insert into EMPLOYEE (birth_date, cell_phone, firstname, lastname)
values (?, ?, ?, ?)
Hibernate: update EMPLOYEE set department_id=?, idx=? where employee_id=?
Hibernate: update EMPLOYEE set department_id=?, idx=? where employee_id=?
Many-to-many
Hibernate
CONSTRAINT `FK_EMPLOYEE` FOREIGN KEY (`employee_id`) REFERENCES `employee`
(`employee_id`),
CONSTRAINT `FK_MEETING` FOREIGN KEY (`meeting_id`) REFERENCES `meeting`
(`meeting_id`)
)
public class Employee {
private Long employeeId;
private String firstname;
private String lastname;
private Set<Meeting> meetings = new HashSet<Meeting>();
public Employee() {
}
public Employee(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
Hibernate
<many-to-many column="MEETING_ID" class="Meeting" />
</set>
</class>
<class name="Meeting" table="MEETING">
<id name="meetingId" type="java.lang.Long"
column="MEETING_ID">
<generator class="native" />
</id>
<property name="subject" column="SUBJECT" />
<property name="meetingDate" type="date" column="MEETING_DATE" />
<set name="employees" table="EMPLOYEE_MEETING"
inverse="true" lazy="true" fetch="select">
<key column="EMPLOYEE_ID" />
<many-to-many column="MEETING_ID" class="Meeting" />
</set>
</class>
</hibernate-mapping>
One thing is worth noting here is that we have mentioned keyword inverse=true in Meeting class
which makes Employee as relationship owner. Thus Employee model takes care of updating
referential keys in dependent models
public class Main {
public static void main(String[] args) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
}
}
session.getTransaction().commit();
session.close();
Hibernate
Output
Hibernate:
Hibernate:
Hibernate:
Hibernate:
Hibernate:
Hibernate:
Hibernate:
insert
insert
insert
insert
insert
insert
insert
into
into
into
into
into
into
into
Many-to-many Annotation
@Entity
@Table(name="EMPLOYEE")
public class Employee {
@Id
@Column(name="EMPLOYEE_ID")
@GeneratedValue
private Long employeeId;
@Column(name="FIRSTNAME")
private String firstname;
@Column(name="LASTNAME")
private String lastname;
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name="EMPLOYEE_MEETING",
joinColumns={@JoinColumn(name="EMPLOYEE_ID")},
inverseJoinColumns={@JoinColumn(name="MEETING_ID")})
private Set<Meeting> meetings = new HashSet<Meeting>();
public Employee() {
}
public Employee(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
// Getter and Setter methods
}
Hibernate
@Entity
@Table(name="MEETING")
public class Meeting {
@Id
@Column(name="MEETING_ID")
@GeneratedValue
private Long meetingId;
@Column(name="SUBJECT")
private String subject;
@Column(name="MEETING_DATE")
private Date meetingDate;
@ManyToMany(mappedBy="meetings")
private Set<Employee> employees = new HashSet<Employee>();
public Meeting(String subject) {
this.subject = subject;
this.meetingDate = new Date();
}
// Getter and Setter methods
}
Component Mappings :
We have seen such mapping while having two tables and using <set>
element in the mapping file.
Now we will use <component> element in the mapping file and a single
table would be used to keep the attributes contained inside the
class variable.
import java.util.*;
public class Employee implements java.io.Serializable {
private int id;
private String firstName;
private String lastName;
private int salary;
Hibernate
private Address address;
public Employee() {}
public Employee(String fname, String lname,
int salary, Address address ) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
this.address = address;
}
getters and setters ...
}
import java.util.*;
public class Address{
private int id;
private String street;
private String city;
private String state;
private String zipcode;
public Address() {}
public Address(String street, String city,
String state, String zipcode) {
this.street = street;
this.city = city;
this.state = state;
this.zipcode = zipcode;
}
getters and setters ...
}
Hibernate
<property name="street" column="street_name" type="string"/>
<property name="city" column="city_name" type="string"/>
<property name="state" column="state_name" type="string"/>
<property name="zipcode" column="zipcode" type="string"/>
</component>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>
</hibernate-mapping>
The <component> element sets the existence of different attributes of
Address class inside Employee classes.
public class App {
public static void main(String[] args) {
System.out.println("Hibernate component mapping");
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Address address = new Address();
address.setStreet("Street");
address.setCity("City");
address.setState("State");
address.setZipCode("ZipcOde");
Customer cust = new Customer();
cust.setCustName("mkyong");
cust.setAge(30);
cust.setAddress(address);
cust.setCreatedDate(new Date());
cust.setCreatedBy("system");
session.save(cust);
session.getTransaction().commit();
System.out.println("Done");
}
INSERT
INTO
mkyongdb.customer
(STREET, CITY, STATE, ZIPCODE, FIRSTNAME, LASTNAME, SALARY)
Hibernate
VALUES
(?, ?, ?, ?, ?, ?, ?)
Hibernate Annotations :
Hibernate Annotations is the powerful way to provide the meta-data for
the Object and Relational Table mapping.
import javax.persistence.*;
@Entity
@Table(name = "EMPLOYEE")
public class Employee {
@Id @GeneratedValue
@Column(name = "id")
private int id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "salary")
private int salary;
public Employee() {}
getters and setters ...
}
@Entity :
@Table :
Hibernate
@Id and @GeneratedValue :
Each entity bean will have a primary key, which you annotate on the
class with the @Id annotation.
@Column :
The @Column annotation is used to specify the details of the column to which a
field or property will be mapped.
You can use column annotation with the following most commonly used
attributes:
Length attribute permits the size of the column used to map a value
particularly for a String value.
Nullable attribute permits the column to be marked NOT NULL when the
schema is generated.
It doesn't depend on the table of the database, instead of table name we use class
name.
HQL queries are translated by Hibernate into conventional SQL queries which in
turns perform action on database.
Although you can use SQL statements directly with Hibernate using
Native SQL but I would recommend to use HQL whenever possible to
avoid database portability hassles, and to take advantage of
Hibernate's SQL generation and caching strategies.
Keywords like SELECT , FROM and WHERE etc. are not case sensitive but
properties like table and column names are case sensitive in HQL.
Hibernate
The main difference between is HQL uses class name instead of table name, and property
names instead of column name.
Advantages :
Database independent
FROM Clause :
You will use FROM clause if you want to load a complete persistent
objects into memory. Following is the simple syntax of using FROM
clause:
If you need to fully qualify a class name in HQL, just specify the
package and class name as follows:
The AS clause can be used to assign aliases to the classes in your HQL
queries, specially when you have long queries. For instance, our
previous simple example would be the following:
specify
the
alias
Without AS keyword
SELECT Clause :
The SELECT clause provides more control over the result set than the
Hibernate
from clause.
WHERE Clause :
If you want to narrow the specific objects that are returned from storage,
you use the WHERE clause. Following is the simple syntax of using WHERE
clause:
String hql = "FROM Employee E WHERE E.id = 10";
Query query = session.createQuery(hql);
List results = query.list();
Using Parameters
String hql = "FROM Employee E WHERE E.id = :empid";
Query query = session.createQuery(hql);
query.setParameter(empid, 10);
List results = query.list();
ORDER BY Clause :
To sort your HQL query's results, you will need to use the ORDER BY
clause. You can order the results by any property on the objects in
the result set either ascending (ASC) or descending (DESC). Following
is the simple syntax of using ORDER BY clause:
String hql = "FROM Employee E WHERE E.id > 10 ORDER BY E.salary DESC";
Query query = session.createQuery(hql);
List results = query.list();
If you wanted to sort by more than one property, you would just add
the additional properties to the end of the order by clause,
separated by commas as follows:
Hibernate
String hql = "FROM Employee E WHERE E.id > 10 " +
"ORDER BY E.firstName DESC, E.salary DESC ";
Query query = session.createQuery(hql);
List results = query.list();
GROUP BY Clause :
This clause lets Hibernate pull information from the database and
group it based on a value of an attribute and, typically, use the
result to include an aggregate value.
This makes writing HQL queries that accept input from the user easy and
you do not have to defend against SQL injection attacks.
UPDATE Clause :
Bulk updates are new to HQL with Hibernate 3, and deletes work
differently in Hibernate 3 than they did in Hibernate 2.
The UPDATE clause can be used to update one or more properties of an one or
more objects.
Hibernate
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);
DELETE Clause :
The DELETE clause can be used to delete one or more objects. Following is the
simple syntax of using DELETE clause:
String hql = "DELETE FROM Employee " +
"WHERE id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);
INSERT Clause :
HQL supports INSERT INTO clause only where records can be inserted from one
object to another object. Following is the simple syntax of using INSERT INTO
clause:
String hql = "INSERT INTO Employee(firstName, lastName, salary)" +
"SELECT firstName, lastName, salary FROM old_employee";
Query query = session.createQuery(hql);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);
Aggregate Methods :
HQL supports a range of aggregate methods, similar to SQL. They work the
same way in HQL as in SQL and following is the list of the available
functions:
S.N.
Functions
Description
avg(property name)
count(property name or *)
max(property name)
min(property name)
sum(property name)
The distinct keyword only counts the unique values in the row set. The following
Hibernate
query will return only unique count:
String hql = "SELECT count(distinct E.firstName) FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();
Criteria query is one which will simply return every object that
corresponds to the Employee class.
Criteria cr = session.createCriteria(Employee.class);
List results = cr.list();
Hibernate
Hibernate
org.hibernate.criterion.LogicalExpression LogicalExpression
org.hibernate.criterion.Restrictions Restrictions
Criteria cr = session.createCriteria(Employee.class);
Criterion salary = Restrictions.gt("salary", 2000);
Criterion name = Restrictions.ilike("firstNname","zara%");
// To get records matching with OR conditions
LogicalExpression orExp = Restrictions.or(salary, name);
cr.add( orExp );
// To get records matching with AND conditions
LogicalExpression andExp = Restrictions.and(salary, name);
cr.add( andExp );
List results = cr.list();
Hibernate
Criteria cr = session.createCriteria(Employee.class);
// To get records having salary more than 2000
cr.add(Restrictions.gt("salary", 2000));
// To sort records in descening order
crit.addOrder(Order.desc("salary"));
// To sort records in ascending order
crit.addOrder(Order.asc("salary"));
List results = cr.list();
Following are the few examples covering different scenarios and can be
used as per requirement:
Criteria cr = session.createCriteria(Employee.class);
// To get total row count.
cr.setProjection(Projections.rowCount());
// To get average of a property.
cr.setProjection(Projections.avg("salary"));
// To get distinct count of a property.
cr.setProjection(Projections.countDistinct("firstName"));
// To get maximum of a property.
cr.setProjection(Projections.max("salary"));
// To get minimum of a property.
cr.setProjection(Projections.min("salary"));
// To get sum of a property.
cr.setProjection(Projections.sum("salary"));
Example,
Session session = factory.openSession();
Transaction tx = null;
Criteria Creation
try{
tx = session.beginTransaction();
Criteria cr = session.createCriteria(Employee.class);
// Add restriction.
Hibernate
Return results
cr.add(Restrictions.gt("salary", 2000));
List employees = cr.list();
Add Restrictions
1. Performance issue
You have no way to control the SQL query generated by Hibernate, if the generated query is slow, you
are very hard to tune the query, and your database administrator may not like it.
2. Maintenance issue
All the SQL queries are scattered through the Java code, when a query went wrong, you may spend
time to find the problem query in your application. On the others hand, named queries stored in the
Hibernate mapping files are much more easier to maintain.
Hibernate
Scalar queries:
The most basic SQL query is to get a list of scalars (values) from one or
more tables.
Following is the syntax for using native SQL for scalar values:
String sql = "SELECT first_name, salary FROM EMPLOYEE";
SQLQuery query = session.createSQLQuery(sql);
query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List results = query.list();
ALIAS_TO_ENTITY_MAP Each row of results is a Map from alias to
entity instance
DISTINCT_ROOT_ENTITY Each row of results is a distinct instance of
the root entity
FULL_JOIN Specifies joining to an entity based on a full join
INNER_JOIN Specifies joining to an entity based on an inner join
LEFT_JOIN Specifies joining to an entity based on a left outer join
PROJECTION This result transformer is selected implicitly by calling
setProjection()
ROOT_ALIAS The alias that refers to the "root" entity of the criteria
query
ROOT_ENTITY Each row of results is an instance of the root entity
If we have Student in a ManyToMany relationship to Department a query
might look like this ...
Session session = (Session) getEntityManager().getDelegate();
Criteria crit = session.createCriteria(Student.class)
.createAlias('departments', 'department');
This query will return duplicates. But set the ResultTransformer as
crit.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
Now the results will be distinct when Hibernate marshalls the results
Example,
public void listEmployeesScalar( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
ResultTransformer
Hibernate
String sql = "SELECT first_name, salary FROM EMPLOYEE";
SQLQuery query = session.createSQLQuery(sql);
query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List data = query.list();
Entity queries:
Note : All Select (*) data will match to Employee.class properties automatically.
Example,
public void listEmployeesEntity( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
String sql = "SELECT * FROM EMPLOYEE";
SQLQuery query = session.createSQLQuery(sql);List of Employee
Objects
query.addEntity(Employee.class);
List employees = query.list();
for (Iterator iterator =
employees.iterator(); iterator.hasNext();){
Employee employee = (Employee) iterator.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
}
tx.commit();
Hibernate
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
The following is the syntax to get entity objects from a native sql
query via addEntity() and using named SQL query.
Hibernate
<column name="STOCK_CODE" length="10" not-null="true" unique="true"
/>
</property>
...
</class>
<query name="findStockByStockCode">
<![CDATA[from Stock s where s.stockCode = :stockCode]]>
</query>
</hibernate-mapping>
Hibernate
/>
</property>
...
</class>
<sql-query name="findStockByStockCodeNativeSQL">
<return alias="stock" class="com.mkyong.common.Stock"/>
<![CDATA[select * from stock s where s.stock_code = :stockCode]]>
</sql-query>
</hibernate-mapping>
You can place a named query inside hibernate-mapping element, but do not put before the class
element, Hibernate will prompt invalid mapping file, all your named queries have to put after the
class element.
Note
Regarding the CDATA , its always good practice to wrap your query text with CDATA, so that the XML
parser will not prompt error for some special XML characters like > , < and etc.
HQL in annotation
@NamedQueries({
@NamedQuery(
name = "findStockByStockCode",
query = "from Stock s where s.stockCode = :stockCode"
)
})
@Entity
Hibernate
@Table(name = "stock", catalog = "mkyong")
public class Stock implements java.io.Serializable {
In native SQL, you have to declare the resultClass to let Hibernate know what is the return type,
failed to do it will caused the exception org.hibernate.cfg.NotYetImplementedException: Pure
native scalar queries are not yet supported.
Hibernate
How To Call Stored Procedure In Hibernate
DELIMITER ;
Hibernate
List result = query.list();
for(int i=0; i<result.size(); i++){
Stock stock = (Stock)result.get(i);
System.out.println(stock.getStockCode());
}
2. NamedNativeQuery in annotation
Declare your store procedure inside the @NamedNativeQueries annotation.
//Stock.java
...
@NamedNativeQueries({
@NamedNativeQuery(
name = "callStockStoreProcedure",
query = "CALL GetStocks(:stockCode)",
resultClass = Stock.class
)
})
@Entity
@Table(name = "stock")
public class Stock implements java.io.Serializable {
...
Hibernate
Query query = session.getNamedQuery("callStockStoreProcedure")
.setParameter("stockCode", "7277");
List result = query.list();
for(int i=0; i<result.size(); i++){
Stock stock = (Stock)result.get(i);
System.out.println(stock.getStockCode());
}
Hibernate
...
</class>
<sql-query name="callStockStoreProcedure">
<return alias="stock" class="com.mkyong.common.Stock"/>
<![CDATA[CALL GetStocks(:stockCode)]]>
</sql-query>
</hibernate-mapping>
From JAVA-T-POINT :
Hibernate Framework :
Hibernate
data access.
The ORM tool internally uses the JDBC API to interact with the
database.
persistent object,
session factory,
transaction factory,
Hibernate
connection factory,
session,
transaction etc.
database layer.
This is the high level architecture of Hibernate with mapping file and
configuration file.
Hibernate
Session :
Hibernate
Transaction :
ConnectionProvider :
TransactionFactory :
Declare getter and setter methods (optional): The Hibernate recognizes the
method by getter and setter method names by default.
Example,
public class Employee {
private int id;
private String firstName,lastName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
Hibernate
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
increment,
hilo,
sequence,
native etc.
Hibernate
<hibernate-mapping>
<class name="com.javatpoint.mypackage.Employee" table="emp1000">
<id name="id">
<generator class="assigned"></generator>
</id>
<property name="firstName"></property>
<property name="lastName"></property>
</class>
</hibernate-mapping>
Hibernate
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class StoreData {
public static void main(String[] args) {
//creating configuration object
Configuration cfg=new Configuration();
cfg.configure("hibernate.cfg.xml");//populates the data of the
configuration file
//creating seession factory object
SessionFactory factory=cfg.buildSessionFactory();
//creating session object
Session session=factory.openSession();
//creating transaction object
Transaction t=session.beginTransaction();
Employee e1=new Employee();
e1.setId(115);
e1.setFirstName("sonoo");
e1.setLastName("jaiswal");
session.persist(e1);//persisting the object
t.commit();//transaction is commited
session.close();
System.out.println("successfully saved");
}
}
Load the jar file :
For successfully running the hibernate application, you should have the
hibernate4.jar file.
Some other jar files or packages are required such as
cglib
log4j
commons
SLF4J
dom4j
xalan
Hibernate
xerces
@Entity
@Table
@Id
@Column etc
Those are all based on the JPA 2 Specification and supports all
features.
Example,
import org.hibernate.*;
import org.hibernate.cfg.*;
public class Test {
public static void main(String[] args) {
Session session = new AnnotationConfiguration()
.configure().buildSessionFactory().openSession();
Transaction t=session.beginTransaction();
Employee e1=new Employee();
e1.setId(1001);
e1.setFirstName("sonoo");
e1.setLastName("jaiswal");
Employee e2=new Employee();
e2.setId(1002);
e2.setFirstName("vimal");
Hibernate
e2.setLastName("jaiswal");
session.persist(e1);
session.persist(e2);
t.commit();
session.close();
System.out.println("successfully saved");
}
}
@UniqueConstraint
Hibernate
@OneToMany(cascade=CascadeType.ALL)
@JoinTable(name="EMPLOYEE_ACCOUNT",
joinColumns={@JoinColumn(name="EMPLOYEE_ID",
referencedColumnName="ID")},
inverseJoinColumns={@JoinColumn(name="ACCOUNT_ID",
referencedColumnName="ID")})
@Embedded
generator classes:
1. assigned
2. increment
3. sequence
4. hilo (high and low)
5. native
6. identity
7. seqhilo (high and low with sequence name)
8. uuid
9. guid
10. select
11. foreign
12.
sequence-identity
Hibernate
Inheritance Mapping Concepts :
1. Table Per Hierarchy
2. Table Per Hierarchy using Annotation
3. Table Per Concrete
4. Table Per Concrete using Annotation
5. Table Per Subclass
6. Table Per Subclass using Annotation
1) Discriminator Concepts :
Hibernate Table Per Hierarchy :
Let's understand the problem first. I want to map the whole hierarchy
given below into one table of the database.
There are three classes in this hierarchy. Employee is the super class
for Regular_Employee and Contract_Employee classes.
Let's
Hibernate
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.javatpoint.mypackage.Employee" table="emp121"
discriminator-value="emp">
<id name="id">
<generator class="increment"></generator>
</id>
<discriminator column="type" type="string"></discriminator>
<property name="name"></property>
<subclass name="com.javatpoint.mypackage.Regular_Employee"
discriminator-value="reg_emp">
<property name="salary"></property>
<property name="bonus"></property>
</subclass>
<subclass name="com.javatpoint.mypackage.Contract_Employee"
discriminator-value="con_emp">
<property name="pay_per_hour"></property>
<property name="contract_duration"></property>
</subclass>
</class>
</hibernate-mapping>
Hibernate
@Inheritance(strategy=InheritanceType.SINGLE_TABLE),
In case of table per hierarchy, only one table is required to map the inheritance
hierarchy.
Here, an extra column (also known as discriminator column) is created in
the table to identify the class.
Example,
import javax.persistence.*;
@Entity
@Table(name = "employee101")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="type",discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue(value="employee")
public class Employee {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
Hibernate
//setters and getters
}
import javax.persistence.*;
@Entity
@DiscriminatorValue("regularemployee")
public class Regular_Employee extends Employee{
@Column(name="salary")
private float salary;
@Column(name="bonus")
private int bonus;
//setters and getters
}
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue("contractemployee")
public class Contract_Employee extends Employee{
@Column(name="pay_per_hour")
private float pay_per_hour;
@Column(name="contract_duration")
private String contract_duration;
//setters and getters
}
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools.
<hibernate-configuration>
<session-factory>
<property name="hbm2ddl.auto">update</property>
-->
Hibernate
<property
name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property
name="connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>
<property name="connection.username">system</property>
<property name="connection.password">oracle</property>
<property
name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<mapping class="com.javatpoint.mypackage.Employee"/>
<mapping class="com.javatpoint.mypackage.Contract_Employee"/>
<mapping class="com.javatpoint.mypackage.Regular_Employee"/>
</session-factory>
</hibernate-configuration>
By union-subclass element
<union-subclass name="com.javatpoint.mypackage.Regular_Employee"
table="regemp122">
Hibernate
<property name="salary"></property>
<property name="bonus"></property>
</union-subclass>
<union-subclass name="com.javatpoint.mypackage.Contract_Employee"
table="contemp122">
<property name="pay_per_hour"></property>
<property name="contract_duration"></property>
</union-subclass>
</class>
</hibernate-mapping>
Example,
In case of Table Per Concrete class, tables are created per class.
Hibernate
The Same Table structure of TPC with out annotation which has
created here
Example,
import javax.persistence.*;
@Entity
@Table(name = "employee102")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Employee {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
//setters and getters
}
Example ,
import javax.persistence.*;
@Entity
@Table(name="regularemployee102")
@AttributeOverrides({
@AttributeOverride(name="id", column=@Column(name="id")),
@AttributeOverride(name="name", column=@Column(name="name"))
})
public class Regular_Employee extends Employee{
@Column(name="salary")
Hibernate
private float salary;
@Column(name="bonus")
private int bonus;
//setters and getters
}
Example,
import javax.persistence.*;
@Entity
@Table(name="contractemployee102")
@AttributeOverrides({
@AttributeOverride(name="id", column=@Column(name="id")),
@AttributeOverride(name="name", column=@Column(name="name"))
})
public class Contract_Employee extends Employee{
@Column(name="pay_per_hour")
private float pay_per_hour;
@Column(name="contract_duration")
private String contract_duration;
getters and setters ...
}
Hibernate
<hibernate-mapping>
<class name="com.javatpoint.mypackage.Employee" table="emp123">
<id name="id">
<generator class="increment"></generator>
</id>
<property name="name"></property>
Parent class
With primary
key
derived class
With foreign key
<joined-subclass name="com.javatpoint.mypackage.Regular_Employee"
table="regemp123">
<key column="eid"></key>
<property name="salary"></property>
<property name="bonus"></property>
</joined-subclass>
derived class
With foreign key
<joined-subclass name="com.javatpoint.mypackage.Contract_Employee"
table="contemp123">
<key column="eid"></key>
<property name="pay_per_hour"></property>
<property name="contract_duration"></property>
</joined-subclass>
</class>
</hibernate-mapping>
Hibernate
Example,
@Entity
@Table(name = "employee103")
Parent class
@Inheritance(strategy=InheritanceType.JOINED)
public class Employee {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
//setters and getters
}
@Entity
Derived class
@Table(name="regularemployee103")
@PrimaryKeyJoinColumn(name="ID")
public class Regular_Employee extends Employee{
@Column(name="salary")
private float salary;
@Column(name="bonus")
private int bonus;
//setters and getters
}
@Entity
@Table(name="contractemployee103")
@PrimaryKeyJoinColumn(name="ID")
public class Contract_Employee extends Employee{
@Column(name="pay_per_hour")
private float pay_per_hour;
@Column(name="contract_duration")
private String contract_duration;
//setters and getters}
Derived class
Hibernate
Hibernate