Saturday, 14 March 2015

Hibernate 1

Hibernate

·         IDE - Integrated Development Environment
·         Ide's will simplify the development process. i.e. IDE carries out the work automatically
Why we need IDE?
As part of IDE all the development and test tools will be integrated.
Followings are the most popular IDE's
·         Eclipse
·         My eclipse
·         RAD
·         Net beans
Hibernate is a framework, this framework will simplify the development process of java application which interact with the database server
A framework is a piece of s/w which contain the code to resolve the commonly occured problems in projects
Hiberate is a alternate tool for JDBC, appart from hibenrate we have so many tool
·         JDA (Java Data Access)
·         JPA(Java Persistent Access)
·         I betes
·         JDO(Java Data Object)
These are tools also called as ORM tools(Object Relation Mapping). These tools represent data in the form of objects
Procedure to hibernate application:
1. Create the hibenrate configuration file
2.Create the pojo class and hbm files
3. develop java application for interacting with DB

1.hiberante.cfg.xml:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
       <property name="hibernate.connection.driver_class">
              oracle.jdbc.driver.OracleDriver</property>
       <property name="hibernate.connection.url">
              jdbc:oracle:thin:@localhost:1521:xe</property>
       <property name="hibernate.connection.username">sql</property>
       <property name="hibernate.connection.password">sql</property>
       <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
       <property name="show_sql">true</property>
       <mapping resource="com/ibm/hbm/Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>

2.POJO class and hbm file:
package com.ibm.beans;

import java.io.Serializable;

public class Employee implements Serializable{
       private static final long serialVersionUID = -639711672600654728L;
       private Integer employeeId;
       private String employeeName;
       private Double employeeSalary;
       //setter and getter methods
}
Employee.hbm.xml:
<?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>
       <class name="com.ibm.beans.Employee" table="EMP">
              <id name="employeeId" column="ENO">
                     <generator class="assigned"/>
              </id>
              <property name="employeeName" column="ENAME"/>
              <property name="employeeSalary" column="SALARY"/>
       </class>
</hibernate-mapping>
3.Java Application
for this we need to follow the some of the steps
1.       create the configuration object
2.       call the configure method
3.       create the session factory object
4.       create session object
5.       start the transaction
6.       represent data in the form of object
7.       Ask the hibernate to perform the operation(save,update,delete,retrive)
8.       end the transaction
9.       close the session
package com.ibm.main;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.ibm.beans.Employee;
import com.ibm.util.LogFile;

public class StoreEmpRecord {
                public static void main(String[] args) {                    
                                Configuration cfg = new Configuration();--------------------1
                                cfg.configure();-----------------------------------------------------2
                                SessionFactory sf = cfg.buildSessionFactory();-------------3
                                Session hsession = sf.openSession();-------------------------4
                                Transaction tx = hsession.beginTransaction();-------------5
                                Employee emp = new Employee();---------------------------6
                                emp.setEmployeeId(12);
                                emp.setEmployeeName("Mamata2");
                                emp.setEmployeeSalary(20001D);
                                hsession.save(emp);----------------------------------------------7
                                tx.commit();---------------------------------------------------------8
                                hsession.close();----------------------------------------------------9
                }
}

Internal Process

1. Only configuration object creates
2.When step 2 is executed hibernate by default search for the default configuration file(hibenrate.cfg.xml). From the configuration file hibernate get the driverclass name, url, username, password and dilect classes. In the hibernate configuration file we configured resourcess(hbm files). Hibenrate reads all the hbm files and stores them jvm's memory
If we wanna create our own configuration file, configure() should be configure(file name);
3.When step 3 is executed hibernate uses the c3p.jar file and create the connection pool. Now hibenrate creates the curd operations and store those queries in the jvm's memory
4. When step 4 is executed hibernate create the session object and first level cache
5. In this step hibernate start the transaction in that transaction we canexecute multiple queries
6. Represent the data in the form of objects
7. When this step is executed hibernate append the pojo object to the first level cache.
8. In this step hibernate checks for any first level cache. if any objects found for operation hibernate do that operation. Now hibernate fill '?' marks with appropriate data
9. When we close the session hibernate removes the first level chache.
Hibernate methods:
@Entity
@Table(name = "EMPLOYEE")
@FilterDef(name = "deletedFilter")
@Filters({ @Filter(name = "deletedFilter", condition = "IS_DELETED_IND = 'N'") })
public class Employee implements Serializable
{
    private static final long serialVersionUID = 5881223793737878802L;
    public static final String EMP_NAME = "empName";
    public static final String EMP_NO = "empNo";
    public static final String SALARY = "empSalary";
    public static final String DELETED_IND = "isDeleted";
    public static final String DELETED_FILTER = "deletedFilter";
    private Integer empNo;
    private String empName;
    private Double empSalary;
    private boolean isDeleted;
    @Id
    @Column(name = "ENO", unique = true, nullable = false, updatable = false, length = 10)
    public Integer getEmpNo()
    {
        return empNo;
    }
    public void setEmpNo(Integer empNo)
    {
        this.empNo = empNo;
    }
    @Column(name = "ENAME" , length = 20, updatable = true)
    public String getEmpName()
    {
        return empName;
    }
    public void setEmpName(String empName)
    {
        this.empName = empName;
    }
    @Column(name = "SALARY", length = 7, precision = 2, updatable = true)
    public Double getEmpSalary()
    {
        return empSalary;
    }
    public void setEmpSalary(Double empSalary)
    {
        this.empSalary = empSalary;
    }
    @Column(name = "IS_DELETED_IND", unique = false, insertable = true, updatable = true, length = 1)
    @Type(type = "yes_no")
    public boolean isDeleted()
    {
        return isDeleted;
    }
    public void setDeleted(boolean isDeleted)
    {
        this.isDeleted = isDeleted;
    }
}
1.        load(Class theClass, Serializable id)
         AnnotationConfiguration cfg = new AnnotationConfiguration();
        cfg.configure();
        SessionFactory sf = cfg.buildSessionFactory();
        Session hsession = sf.openSession();
        Transaction tx = hsession.beginTransaction();
        Employee emp = new Employee();-------------------------1
        hsession.load(emp,1);----------------------------------2
        System.out.println(emp.getEmpName());
        tx.commit();-------------------------------------------3
     hsession.close();
·         When step 1 is executed, it will create the product class object and load that object with default values.
·         When step 2 is executed hibernate find the which pojo class object was created and then hibernate find the table name from mapping then hibernate get the select query. In our case hibernate retrieve the following query In our case hibernate retrieve the "select pid, pname, price from product where pid=?". Now hibernate replace the ? mark with passed value. Now hibernate send the query to the database server, server return the result set object to the hibernate, then hibernate store these data into the pojo class
·         When step 3 is executed hibernate add pojo class to the first level  cache.
2.       get(Class clazz, Serializable id) 
        AnnotationConfiguration cfg = new AnnotationConfiguration();
        cfg.configure();
        SessionFactory sf = cfg.buildSessionFactory();
        Session hsession = sf.openSession();
        Transaction tx = hsession.beginTransaction();
        Object o = hsession.get(Employee.class, 1);
        if (o != null)
        {
            Employee emp = (Employee) o;
            System.out.println(emp.getEmpName());
        }
        else
        {
            System.out.println("object not found");
        }
        tx.commit();
        hsession.close();
 get() will retrieve data, if data is available in the data base. This method returns the null when data is not present in DB.
        
3.       delete:
If we want to delete record from DB we have two approches.
Approch1:
·         Create pojo class onject
·         load data into pojo class
·         fire delete command
·         commit the transaction
         AnnotationConfiguration cfg = new AnnotationConfiguration();
        cfg.configure();
        SessionFactory sf = cfg.buildSessionFactory();
        Session hsession = sf.openSession();
        Transaction tx = hsession.beginTransaction();
        Employee emp =new Employee();--------------------------1
        hsession.load(emp, 1);---------------------------------2
        hsession.delete(emp);----------------------------------3
        tx.commit();-------------------------------------------4
         hsession.close();
·         When step 1 is executed hibernate create the employee object and assign with the default values
·         When step 2 is executed hibernate load the data into employee object and adds this object to the first level cache without any registration code
·         Step 3 is executed hibernate mark the object to delete
·         Step 4 is executed hibernate checks any objects are ready for taking an action. In this case one object is ready to delete action so hibernate send the delete query to the DB
In this approach hibernate throws object not found exception because data is not present hibernate load method throws the exception. This approch is not best approch
Approach 2:
·         Create pojo class object
·         set primary key
·         delete object
·         commit
         AnnotationConfiguration cfg = new AnnotationConfiguration();
        cfg.configure();
        SessionFactory sf = cfg.buildSessionFactory();
        Session hsession = sf.openSession();
        Transaction tx = hsession.beginTransaction();
        Employee emp =new Employee();----------------------------1
        emp.setEmpNo(1);
        emp.setEmpName("Chandra");---------------------------------2
        emp.setEmpSalary(40000d);
        hsession.delete(emp);--------------------------------------3
        tx.commit();-----------------------------------------------4
  hsession.close();
·         Step 1: creates the pojo object and initialize with default values
·         Step2 : assigning with the primary key data
·         Step3 : On first level cache marking it as a deleted
·         Step4 : sends the delete query if data is present in Db
This is best approach because if data present in Db then only delete query sends to DB.
4.       Update
                This we can do in two ways
                Approach 1: Hibernate automatically sends the update query to Db if object is dirty. Dirty object if we change the state of an object that object is called as dirty object
         AnnotationConfiguration cfg = new AnnotationConfiguration();
        cfg.configure();
        SessionFactory sf = cfg.buildSessionFactory();
        Session hsession = sf.openSession();
        Transaction tx = hsession.beginTransaction();
        Employee emp = new Employee();--------------------------1
        hsession.load(emp, 1);----------------------------------2
        emp.setEmpName("Reddy");--------------------------------3
        tx.commit();--------------------------------------------4
        hsession.close();
·         Step1 : Creates the object and initialize with default values
·         Step2 : loads the employee data
·         Step3 : setting loaded object into dirty
·         Step4 : Hibernate automatically checks for dirty objects and sends them to the DB
Approch2:  Create the pojo class, set data into pojo class, call update() and commit transaction.
AnnotationConfiguration cfg = new AnnotationConfiguration();
cfg.configure();
SessionFactory sf = cfg.buildSessionFactory();
Session hsession = sf.openSession();
Transaction tx = hsession.beginTransaction();
Employee emp = new Employee();----------------------------------1
emp.setEmpName("Reddy");
emp.setEmpNo(1);------------------------------------------------2
hsession.update(emp);-------------------------------------------3
tx.commit();----------------------------------------------------4
hsession.close();
·         Step1 : Pojo class object would created and initialize with default values
·         Step2: Updating with our expected data
·         Step3: add pojo object to first level cache with tbu key
·         Step4:hibenrate sends the data to DB
This mechanism is not effective because whatever data we are providing that data sends to DB and remaining data removes from the DB. Here it big bug in data
5.       Evict
This method removes any object from the first level cache.
        AnnotationConfiguration cfg = new AnnotationConfiguration();
        cfg.configure();
        SessionFactory sf = cfg.buildSessionFactory();
        Session hsession = sf.openSession();
        Transaction tx = hsession.beginTransaction();
        Employee emp = new Employee();
        emp.setEmpName("Reddy1");
        emp.setEmpNo(1);
        hsession.update(emp);
        hsession.evict(emp);
        tx.commit();
        hsession.close();
6.       Merge:
                It works in 3 ways
·         If data is not present with id hibernate sends insert query
·         If data present in DB with the ID and object is contains different data with DB record, hibernate sends the update query
·         If data present in Db with the id and no changes on session object and db record system doesn't sends any record to Db

        AnnotationConfiguration cfg = new AnnotationConfiguration();
        cfg.configure();
        SessionFactory sf = cfg.buildSessionFactory();
        Session hsession = sf.openSession();
        Transaction tx = hsession.beginTransaction();
        Employee emp = new Employee();
        emp.setEmpName("Reddy1");
        emp.setEmpNo(2);
        hsession.merge(emp);
        tx.commit();
  hsession.close();
7.       Clear: Removes all the first level cache objects
        AnnotationConfiguration cfg = new AnnotationConfiguration();
        cfg.configure();
        SessionFactory sf = cfg.buildSessionFactory();
        Session hsession = sf.openSession();
        Transaction tx = hsession.beginTransaction();
        Employee emp = new Employee();
        emp.setEmpName("Reddy2");
        emp.setEmpNo(2);
        hsession.merge(emp);
        hsession.clear();
        tx.commit();
        hsession.close();

8.       Flush: Sends all the queries to DB without transaction commit()

        AnnotationConfiguration cfg = new AnnotationConfiguration();
        cfg.configure();
        SessionFactory sf = cfg.buildSessionFactory();
        Session hsession = sf.openSession();
        Transaction tx = hsession.beginTransaction();
        Employee emp = new Employee();
        emp.setEmpName("Reddy2");
        emp.setEmpNo(2);
        hsession.merge(emp);
        hsession.flush();
        hsession.close();

9.       Contains:
        AnnotationConfiguration cfg = new AnnotationConfiguration();
        cfg.configure();
        SessionFactory sf = cfg.buildSessionFactory();
        Session hsession = sf.openSession();
        Transaction tx = hsession.beginTransaction();
        Employee emp = new Employee();
        hsession.load(emp, 1);
        System.out.println(hsession.contains(emp));
        tx.commit();
        hsession.close();

show_sql property:

This property displays the queries which are sent by hibernate to DB. This property we need to configure in hibernate configuration file. Default value of this property is false. When we set this property to true system displays the queries in the console.
<property name="show_sql">true</property>

hbm2ddl_auto:

This property is used to create the table in the DB by using hibernate. For this we have multiple values. If value is create hibernate will create the table in DB server.
validate | update | create | create-drop

Uses of wrapper classes in hibernate:

In POJO classes it's recommended to use wrapper classes instead of primitive data types. Primitive data types will occupy less memory even though it is recommended to use wrapper classes.
·         Primitive data types won't allow null values but wrapper class objects allows null values
·         While retrieving the from data base data is null and we are trying to assign it to primitive data types system will fail to assign null value to primitive data.
·         While storing data if we don't pass the value to primitive data types system stores the default values of primitive types. for example price(double) we are not passing any value to it and by default it stores the 0.0 on price column.
Because of above reasons it's recommended to provide the Wrapper classes.
@Entity
@Table(name = "EMPLOYEE")
@FilterDef(name = "deletedFilter")
@Filters({ @Filter(name = "deletedFilter", condition = "IS_DELETED_IND = 'N'") })
public class EmployeePrimitive implements Serializable
{
    private int empNo;

    private String empName;

    private double empSalary;

    private boolean isDeleted;

}
         AnnotationConfiguration cfg = new AnnotationConfiguration();
        cfg.configure();
        SessionFactory sf = cfg.buildSessionFactory();
        Session hsession = sf.openSession();
        Transaction tx = hsession.beginTransaction();
        EmployeePrimitive emp = new EmployeePrimitive();
        hsession.load(emp, 1);
        tx.commit();
        hsession.close();
When we execute above program system throws the exception

Exception in thread "main" org.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter of com.ibm.pdc.ephs.hibernate.domain.EmployeePrimitive.empSalary

No comments:

Post a Comment