Showing posts with label ORM. Show all posts
Showing posts with label ORM. Show all posts

Wednesday, June 5, 2013

Sample Hibernate Application Using Eclipse and using annotations

In first example, I have created sample Hibernate project using mapping files
Next step is to convert same application to use annotations.
Change Employee.java and Department.java files to use annotations as shown below.

Employee.java

package com.test.beans;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name="EMP")
public class Employee {
@Id @GeneratedValue
@Column(name="emp_id")
private Long empId;
@Column(name="first_name")
private String firstName;
@Column(name="last_name")
private String lastName;
@Column(name="degn")
private String designation;
@Column(name="sal")
private double salary;
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="dept")
private Department dept;
public Long getEmpId() {
return empId;
}
public void setEmpId(Long empId) {
this.empId = empId;
}
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;
}
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public Department getDept() {
return dept;
}
public void setDept(Department dept) {
this.dept = dept;
}
}

Department.java:

package com.test.beans;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="DEPT")
public class Department {
@Id @GeneratedValue
@Column(name="dept_id")
private long deptId;
@Column(name="dept_name")
private String deptName;
@Column(name="loc")
private String location;
public long getDeptId() {
return deptId;
}
public void setDeptId(long deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}

Change hibernate.cfg.xml file as:

  <? xml version="1.0" encoding="UTF-8"?>


<!

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


<hibernate-configuration>



<session-factory>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hbm2ddl.auto">create</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hibernate.use_sql_comments">true</property>

<mapping class="com.test.beans.Employee" />
<mapping class="com.test.beans.Department" /> 
</session-factory>
</hibernate-configuration>


You can delete (organization.hbm.xml) hbm mapping file.

Now your sample annotation project is ready. You can run Test.java file to check the output.

Sunday, June 2, 2013

Automatic Dirty checking and Transaction write-behind concepts of Hibernate

Hibernate uses a sophisticated algorithm to determine an efficient ordering that avoids database foreign key constraint violations but is still sufficiently predictable to the user. This feature is called transaction write-behind.

Automatic Dirty checkingIf object which is already saved is modified, then Hibernate automatically call update on that object.
Hibernate is capable of detecting all objects that are modified or are dirty. It is done with the help of PersistanceContext.
Within PersistanceContext, Hibernate has copy of all persistent objects that are loaded from database in Session. It compares persistent object to determine whether object is modified.


Hibernate allows implementation of custom dirty checking algorithm. This is done by implementing findDirty() method of org.hibernate.Interceptor interface for a Session.

Friday, May 31, 2013

Sample Hibernate Application Using Eclipse using mapping file

Here are steps to create sample hibernate application using eclipse. I am using hibernate version 4.2 and MySQL database for reference.
First I will create it using mapping xml file. Then convert same application to use annotation and finally JPA.
Create Java Project as:

Create java project - HibernateJPA

Create below packages in src folder by using option "create package"
com.test.beans
com.test.resources
com.test.dao
com.test.util

Add hibernate dependencies for project by right clicking on project "Build Path" --> Configure Build Path.
Under Libraries Tab: Add external jar button and add Hibernate required jar files.
  • antlr-2.7.7.jar
  • dom4j-1.6.1.jar
  • hibernate-commons-annotations-4.0.1.Final.jar
  • hibernate-core-4.2.0.Final.jar
  • hibernate-jpa-2.0-api-1.0.1.Final.jar
  • javassist-3.15.0-GA.jar
  • jboss-logging-3.1.0.GA.jar
  • jboss-transaction-api_1.1_spec-1.0.0.Final.jar
Also add mysql connector jar.
  • mysql-connector-java-3.1.14-bin.jar
 Create HibernateUtil.java file under package com.test.util for creating and using SessionFactory object as:
For more details about building SessionFactory refer post Creating SessionFactory.
HibernateUtil.java


package com.test.util;



import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;



public class HibernateUtil {
       private static SessionFactory sessionFactory;

static{
       try {
               sessionFactory = new Configuration().configure("com/test/resources/hibernate.cfg.xml").buildSessionFactory();


       }

       catch (Exception e) {                
           throw new ExceptionInInitializerError(e);
       }

   }


public static SessionFactory getSessionFactory(){
     return sessionFactory;
}
public static void shutDown(){
      getSessionFactory().close();
}
}
 
 Employee and Department classes which are persistace objects in package com.test.beans:

Employee.java



package  com.test.beans;





public class Employee {



private Long empId;
private String firstName;
private String lastName;
private String designation;
private double salary;
private Department dept;
public Long getEmpId() {
        return empId;
}
public void setEmpId(Long empId) {
        this.empId = empId;
}
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;
}
public String getDesignation() {
       return designation;
}
public void setDesignation(String designation) {
       this.designation = designation;
}
public double getSalary() {
      return salary;
}
public void setSalary(double salary) {
     this.salary = salary;
}
public Department getDept() {
     return dept;
}
public void setDept(Department dept) {
     this.dept = dept;
}
}


Department.java 

package  com.test.beans;

public class Department {
private long deptId;

private String deptName;
private String location;



public long getDeptId() {

         return deptId;
}
public void setDeptId(long deptId) {
           this.deptId = deptId;
}

public String getDeptName() {
          return deptName;


}


public void setDeptName(String deptName) {
         this.deptName = deptName;
}
public String getLocation() {
         return location;


}


public void setLocation(String location) {
         this.location = location;
}
}
We need hibernate configuration file for settings related to connecting database. (configuration file contains much more but for simple application, i am only defining minimum required settings)

hibernate.cfg.xml

  <? xml version="1.0" encoding="UTF-8"?>


<!

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


<hibernate-configuration>



<session-factory>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hbm2ddl.auto">create</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hibernate.use_sql_comments">true</property>
<mapping resource="com/test/beans/organization.hbm.xml" />
</session-factory>
</hibernate-configuration>



Now we need mapping file which defines mapping of Persistance classes with database tables:

organization.hbm.xml



< xml version="1.0"?>



<!



DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


package="com.test.beans">
<class name="Department" table="DEPT">
     <id name="deptId" column="dept_id">
               <generator class="native" />
     </id>
     <property name="deptName" type="string" column="dept_name" unique="true"/>
     <property name="location" type="string" column="loc"/>
</class>
<class name="Employee" table="EMP" >
       <id name="empId" column="emp_id">
                 <generator class="native"></generator>
       </id>
       <property name="firstName" type="string" column="first_name" />
       <property name="lastName" type="string" column="last_name" />
       <property name="designation" type="string" column="degn" />
       <property name="salary" type="double" column="sal" />
       <many-to-one name="dept" column="dept"  class="Department" />
</class>
</hibernate-mapping>



Hibernate application is ready and let's create test class to test the application.

Test.java




package com.test.dao;



import org.hibernate.Session;
import org.hibernate.Transaction;
import com.test.beans.Department;
import com.test.beans.Employee;
import com.test.util.HibernateUtil;

public  class Test {



public static void main(String[] args) {
          Employee emp = new Employee();
          emp.setFirstName("fName");
          emp.setLastName("lName");
          emp.setDesignation("Java Developer");
          emp.setSalary(20000);
          Department dept= new Department();         
          dept.setDeptName("Design");         
          emp.setDept(dept);        
          Session sess = HibernateUtil.getSessionFactory().openSession();
         Transaction tran = sess.beginTransaction();
         sess.save(emp);
         sess.flush();
         tran.commit();
         sess.close();
}
}
After running above class, Employee and Department data is stored in respective tables. You get console log to understand how hibernate works in background.
Console Log:






May 31, 2013 7:18:36 PM org.hibernate.annotations.common.Version


INFO: HCANN000001: Hibernate Commons Annotations {4.0.1.Final}

May 31, 2013 7:18:36 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.2.0.Final}
May 31, 2013 7:18:36 PM org.hibernate.cfg.Environment
INFO: HHH000206: hibernate.properties not found
May 31, 2013 7:18:36 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
May 31, 2013 7:18:36 PM org.hibernate.cfg.Configuration configure
INFO: HHH000043: Configuring from resource: com/test/resources/hibernate.cfg.xml
May 31, 2013 7:18:36 PM org.hibernate.cfg.Configuration getConfigurationInputStream
INFO: HHH000040: Configuration resource: com/test/resources/hibernate.cfg.xml
May 31, 2013 7:18:36 PM org.hibernate.internal.util.xml.DTDEntityResolver resolveEntity
WARN: HHH000223: Recognized obsolete hibernate namespace http://hibernate.sourceforge.net/. Use namespace http://www.hibernate.org/dtd/ instead. Refer to Hibernate 3.6 Migration Guide!
May 31, 2013 7:18:36 PM org.hibernate.cfg.Configuration addResource
INFO: HHH000221: Reading mappings from resource: com/test/beans/organization.hbm.xml
May 31, 2013 7:18:36 PM org.hibernate.internal.util.xml.DTDEntityResolver resolveEntity
WARN: HHH000223: Recognized obsolete hibernate namespace http://hibernate.sourceforge.net/. Use namespace http://www.hibernate.org/dtd/ instead. Refer to Hibernate 3.6 Migration Guide!
May 31, 2013 7:18:36 PM org.hibernate.cfg.Configuration doConfigure
INFO: HHH000041: Configured SessionFactory: null
May 31, 2013 7:18:36 PM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)
May 31, 2013 7:18:36 PM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20
May 31, 2013 7:18:36 PM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000006: Autocommit mode: false
May 31, 2013 7:18:36 PM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/test]
May 31, 2013 7:18:36 PM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000046: Connection properties: {user=root, password=****}
May 31, 2013 7:18:36 PM org.hibernate.dialect.Dialect
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
May 31, 2013 7:18:36 PM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
May 31, 2013 7:18:36 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
May 31, 2013 7:18:36 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory
INFO: HHH000397: Using ASTQueryTranslatorFactory
May 31, 2013 7:18:36 PM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000227: Running hbm2ddl schema export




Hibernate:


alter table Employee
drop
foreign key FK4AFD4ACEF1062AF1
Hibernate:
drop table if exists DEPT
Hibernate:
drop table if exists Employee
Hibernate:
create table DEPT (
dept_id bigint not null auto_increment,
dept_name varchar(255),
loc varchar(255),
primary key (dept_id)
)
Hibernate:
create table Employee (
MESSAGE_ID bigint not null auto_increment,
first_name varchar(255),
last_name varchar(255),
degn varchar(255),
sal double precision,
dept bigint,
primary key (MESSAGE_ID)
)
Hibernate:
alter table DEPT
add constraint uc_DEPT_1 unique (dept_name)
Hibernate:
alter table Employee
add index FK4AFD4ACEF1062AF1 (dept),
add constraint FK4AFD4ACEF1062AF1
foreign key (dept)
references DEPT (dept_id)







May 31, 2013 7:18:37 PM org.hibernate.tool.hbm2ddl.SchemaExport execute

INFO: HHH000230: Schema export complete








Hibernate:


/* insert com.test.beans.Department
*/ insert
into
DEPT
(dept_name, loc)
values
(?, ?)
Hibernate:
/* insert com.test.beans.Employee
*/ insert
into
Employee
(first_name, last_name, degn, sal, dept)
values
(?, ?, ?, ?, ?)

To convert same application to use Annotations, Refer next post.