Recent Posts

Sunday, 15 May 2016

Setting Hibernate Environment


* To work with hibernate framework we need to add .jar(s) files provided by that framework to our java application.

* No framework is installable software, it means we doesn't contain any setup.exe

* When we download any framework, we will get a 'zip' file and we need to unzip it, to get the required jar files, actually all frameworks will follow same common principles like ...
1. Framework will be in the form of a set of jar files, where one jar file acts as main (We can call this file as core) and remaining will acts as dependent jar files.

2. Each Framework contain at least one configuration xml file, but multiple configuration files also allowed.

* We can download hibernate jar files from the following links. Based on requirement we can download the corresponding version.
For version 2.x (http://sourceforge.net/projects/hibernate/files/hibernate2/)
For version 3.x (http://sourceforge.net/proiects/hibernate/f1les/hibernate3/)
For version 4.x (http://sourceforge.net/projects/hibernate/f1Ies/hibernate4/)
* While downloading select .zip file for windows environment, select .tar flle for unix environment.

* After downloading the zip file, unzip it and we can find the required jars in the extracted folder. If we consider 4.x version, we need the following jars to work with hibernate application.
antlr-2.7.7.jar
dom4j-1.6.1.jar
hibernate-commons-annotations-4.0.2.Final.jar
hibernate-core-4.2.4.Final.jar
hibernate-jpa-2.0-api-1.0.1.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.1.Final.jar

Note
     Along with the hibernate jars we must include one more jar file, which is nothing but related to our database, this is depending on your database. For example, if we are working with Oracle we need to add ojdbc6.jar.

Steps to develop hibernate applications
Step 1: Develop persistent/domain/entity class for each table of the relational model
Step 2: For each entity develop a mapping file
Step 3: Develop the configuration file
Step 4: Add hibernate framework jar files in the classpath
Step 5: Make use of hibernate API and perform persistent operations

How to make use of hibernate API to perform persistent operations
Step 1: Create Configuration object
Configuration configuration = new Configuration();
Step 2: Read configuration file along with mapping files using configure() method of Configuration Object
configuration.configure();
Step 3: Build a SessionFactory from Configuration
SessionFactory factory = configuration.buildSessionFactory();
Step 4: Get Session from SessionFactory object
Session session = factory.openSession();
Step 5: Create a logical transaction
     While working with insert, update, delete operations from an hibernate application onto the database then hibernate needs a logical Transaction, if we are selecting an object from the database then we do not require any logical transaction in hibernate.  In order to begin a logical transaction in hibernate then we need to call a method beginTransaction() given by Session Interface.
Transaction tx = session.beginTransaction();
Step 6: Perform persistence operations
     The Session interface provides methods to perform CRUD (Create Read Update Delete) operations on the instances of mapped entity classes. Perform transactions if require while performing DML operations. Session interface methods are
session.save(s)   - Inserting object ‘s’ into database
session.update(s) - Updating object ‘s’ in the database
session.load(s)   - Selecting objcet ‘s’ object
session.delete(s) - Deleting object ‘s’ from database
     So finally we need to call commit() in Transaction, like tx.commit();
Step 7: Finally close the Session as session.close() and finally close the SessionFactory as sf.close().
Final flow will be
1. Configuration
2. SessionFactory
3. Session
4. Transaction
5. Close Statements

Develop Hibernate application, in which we can perform account creation, retrieve, update and delete
MySQL Create Table Query
CREATE TABLE account (
  ACCNO int(10) NOT NULL,
  NAME varchar(45) NOT NULL,
  BAL dec(9,2) NOT NULL,
  CREATION_DATE date NOT NULL,
  PRIMARY KEY (ACCNO)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
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>
   <session-factory>
      <property name="hibernate.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/hibernate</property>
      <property name="hibernate.connection.username">root</property>
      <property name="hibernate.connection.password">ashok</property>

      <property name="hbm2ddl.auto">update</property>

      <mapping resource="com/ashok/hibernate/bean/Account.hbm.xml"/>
   </session-factory>
</hibernate-configuration>
SessionUtil.java
package com.ashok.hibernate.util;

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

public class SessionUtil {
   private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); 
   private static org.hibernate.SessionFactory sessionFactory;
   static {
      try {
         sessionFactory= new Configuration()
         .configure("com/ashok/hibernate/config/hibernate.cfg.xml")
         .buildSessionFactory();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
   private SessionUtil() {
   }
   public static Session getThreadLocalSession() {
      Session session = (Session) threadLocal.get();
      session = sessionFactory.openSession();
      if (session == null) {   
         threadLocal.set(session); 
      }
      return session;
   }
   public static void closeThreadLocalSession() {
      Session session = (Session) threadLocal.get();
      threadLocal.set(null);
      if (session != null) {
         session.close();
      }
   }
   public static Session getSession() {   
      return sessionFactory.openSession();
   }
   public static void closeSession(Session session) {
      if (session != null) {
         session.close();
      }
   }
}
Account.java
package com.ashok.hibernate.bean;

import java.util.Date;

public class Account {
   private long accno;
   private String name;
   private double balance;
   private Date creationDate;

   public long getAccno() {
      return accno;
   }

   public void setAccno(long accno) {
      this.accno = accno;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public double getBalance() {
      return balance;
   }

   public void setBalance(double balance) {
      this.balance = balance;
   }

   public Date getCreationDate() {
      return creationDate;
   }

   public void setCreationDate(Date creationDate) {
      this.creationDate = creationDate;
   }

   @Override
   public String toString() {
      return "Account [accno=" + accno + ", name=" + name + ", balance="
            + balance + ", creationDate=" + creationDate + "]";
   }
}
Account.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
   <class name="com.ashok.hibernate.bean.Account" table="account">
      <id name="accno" type="long">
         <column name="ACCNO" length="10" not-null="true"></column>
      </id>
      <property name="name" type="string">
         <column name="NAME" length="45" not-null="true"></column>
      </property>
      <property name="balance" type="double">
         <column name="BAL" precision="9" scale="2" not-null="true"></column>
      </property>
      <property name="creationDate " type="date">
         <column name="CREATION_DATE" not-null="true"></column>
      </property>
   </class>
</hibernate-mapping>
AccountDAO.java
package com.ashok.hibernate.dao;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.ashok.hibernate.bean.Account;
import com.ashok.hibernate.util.SessionUtil;

public class AccountDAO {
   public Account get(long accno) {
      Session session = null;
      Account account = null;
      try {
         session = SessionUtil.getSession();
         account = (Account) session.get(Account.class, accno);
      } catch (HibernateException e) {
         e.printStackTrace();
      } finally {
         SessionUtil.closeSession(session);
      }
      SessionUtil.closeSession(session);
      return account;
   }

   public void insert(Account account) {
      Session session = null;
      try {
         session = SessionUtil.getSession();
         session.getTransaction().begin();
         session.save(account);
         session.getTransaction().commit();
      } catch (HibernateException e) {
         session.getTransaction().rollback();
         e.printStackTrace();
      } finally {
         SessionUtil.closeSession(session);
      }
   }

   public void update(Account account) {
      Session session = null;
      try {
         session = SessionUtil.getSession();
         session.getTransaction().begin();
         session.update(account);
         session.getTransaction().commit();
      } catch (HibernateException e) {
         session.getTransaction().rollback();
         e.printStackTrace();
      } finally {
         SessionUtil.closeSession(session);
      }
   }

   public void delete(long accno) {
      Session session = null;
      Transaction transaction = null;
      try {
         session = SessionUtil.getSession();
         transaction = session.beginTransaction();
         Account account = (Account) session.get(Account.class, accno);
         session.delete(account);
         transaction.commit();
      } catch (HibernateException e) {
         transaction.rollback();
         e.printStackTrace();
      } finally {
         SessionUtil.closeSession(session);
      }
   }
}
AccountService.java
package com.ashok.hibernate.service;

import java.util.Date;
import com.ashok.hibernate.bean.Account;
import com.ashok.hibernate.dao.AccountDAO;

public class AccountService {
   public static void main(String[] args) {
      AccountDAO dao = new AccountDAO();

      // Retrieve Account
      Account rAccount = dao.get(90001);
      System.out.println("Account details ....");
      System.out.println("Accno : " + rAccount.getAccno());
      System.out.println("Name : " + rAccount.getName());
      System.out.println("Balance : " + rAccount.getBalance());
      System.out.println("Creation Date: " + rAccount.getCreationDate());

      // Create Account
      Account cAccount = new Account();
      cAccount.setAccno(90005);
      cAccount.setName("Ashok");
      cAccount.setBalance(6899);
      cAccount.setCreationDate(new Date());
      dao.insert(cAccount);
      System.out.println("Account created successfully");

      // Update Account
      Account uAccount = new Account();
      uAccount.setAccno(90003);
      uAccount.setName("Ashok Kumar");
      uAccount.setBalance(4500);
      uAccount.setCreationDate(new Date());
      dao.update(uAccount);
      System.out.println("Account updated successfully");

      // Delete Account
      dao.delete(90002);
      System.out.println("Account is deleted successfully");
   }
}
Rewrite the above application, using annotations instead of mapping file 
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>
   <session-factory>
      <property name="hibernate.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/hibernate</property>
      <property name="hibernate.connection.username">root</property>
      <property name="hibernate.connection.password">ashok</property>
 
      <property name="hbm2ddl.auto">update</property>
 
      <mapping class="com/ashok/hibernate/bean/Account"/>
   </session-factory>
</hibernate-configuration>
SessionUtil.java
package com.ashok.hibernate.util;

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

public class SessionUtil {
   private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
   private static org.hibernate.SessionFactory sessionFactory;
   static {
      try {
         sessionFactory= new AnnotationConfiguration()
         .configure("com/ashok/hibernate/config/hibernate.cfg.xml")
         .buildSessionFactory();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
   private SessionUtil() {
   }
   public static Session getThreadLocalSession() {
      Session session = (Session) threadLocal.get();
      session = sessionFactory.openSession();
      if (session == null) {
         threadLocal.set(session);
      }
    return session;
   }
   
   public static void closeThreadLocalSession() {
      Session session = (Session) threadLocal.get();
      threadLocal.set(null);
      if (session != null) {
         session.close();
      }
   }

   public static Session getsession() {
      return sessionFactory.openSession();
   }

   public static void closeSession(Session session) {
      if (session != null) {
         session.close();
      }
   }
}
Account.java
package com.ashok.hibernate.bean;

import javax.persistence.*;
import java.util.Date;

@Entity
@Table(name="ACCOUNT")
public class Account {
   private long accno;
   private String name;
   private double balance;
   private Date creationDate;

   @Id
   @Column(name = "ACCNO", nullable =true, length=10)
   public long getAccno() {
      return accno;
   }
   public void setAccno(long accno) {
      this.accno = accno;
   }

   @Column(name = "NAME", nullable =true, length=45)
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
  
   @Column(name = "BAL", nullable =true, precision="9", scale="2")
   public double getBalance() {
      return balance;
   }
   public void setBalance(double balance) {
      this.balance = balance;
   }

   @Temporal(TemporalType.DATE)
   @Column(name = "CREATION_DATE", nullable =true)
   public Date getCreationDate() {
      return creationDate;
   }
   public void setCreationDate(Date creationDate) {
      this.creationDate = creationDate;
   }

   @Override
   public String toString() {
      return "Account [accno=" + accno + ", name=" + name + ", balance="
      + balance + ", creationDate=" + creationDate + "]";
   }
}
Account.hbm.xml
---Not Required---

AccountDAO.java
---Same As Above---

AccountService.iava
---Same As Above---

Hibernate - The type AnnotationConfiguration is deprecated Problem
     Working with Hibernate 3.6, noticed the previous "org.hibernate.cfg.AnnotationConfiguration", is marked as "deprecated".
Code snippets
private static SessionFactory buildSessionFactory() {
   try {
      return new AnnotationConfiguration().configure().buildSessionFactory();
   } catch (Throwable ex) {
      System.err.println("Initial SessionFactory creation failed." + ex);
      throw new ExceptionlnlnitializerError(ex);
   }
}
     The code is still working, just keep displaying the deprecated warning message, is there any replacement for "AnnotationConfiguration" ?
Solution
     In Hibernate 3.6, "org.hibernate.cfg AnnotationConfiguration" is deprecated, and all its functionality has been moved to "org.hibernate.cfg.Configuration". SO, you can safely replace your "AnnotationConfiguration" with "Configuration' class.
Code snippets
private static SessionFactory buildSessionFactory() {
   try {
      return new Configuration().configure().buildSessionFactory();
   } catch (Throwable ex) {
      System.err.println("Initial SessionFactory creation failed." + ex);
      throw new ExceptionlnlnitializerError(ex);
   }
}
Next Tutorial  More About Hibernate Configuration and Mapping Filles

Previous Tutorial  Hibernate Basic Tutorial

2 comments: