14 September, 2014

Many-to-One relationship in hibernate - @ManyToOne Example

As we all know Hibernate is an easy and fast framework for work with any Database using Java language. This example show how to work with Many-To-One relationship in Hibernate.


I have used MySQL as database (Download Here) and Hibernate 3 jar files (Download Here). Also for applying Many-To-One relation we have used annotation. Even you can do this by using .xml config also, but that's too old and no one is using that now-a-days.

Create table department and employee :-

 Table department :
CREATE TABLE `department` (
  `deptid` int(11) NOT NULL,
  `deptname` varchar(100) default NULL,
  PRIMARY KEY  (`deptid`)
) ENGINE=InnoDB DEFAULT CHARSET=big5;


Table employee :
CREATE TABLE `employee` (
  `empid` int(11) NOT NULL,
  `empname` varchar(50) default NULL,
  `deptno` int(11) default NULL,
  PRIMARY KEY  (`empid`),
  KEY `deptno` (`deptno`),
  CONSTRAINT `employee_ibfk_1` FOREIGN KEY (`deptno`) REFERENCES `department` (`deptid`)
) ENGINE=InnoDB DEFAULT CHARSET=big5;
In this above both table , many employee could be from one department and implements Many-to-One relationship.


hibernate.cnf.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>
        <!-- Adding mysql dialect -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
           <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <!-- Here jdeveloperguidedb is the database name -->
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/jdeveloperguidedb</property>
           <property name="hibernate.connection.username">root</property>
           <property name="hibernate.connection.password">root</property>
           <!-- show_sql property will help you to show the generated hibernate query on console -->          
           <property name="show_sql" >true</property> 
           <!-- Mapping entity class to hibernate -->
           <mapping class="com.jdeveloperguide.lab.Employee"></mapping> 
           <mapping class="com.jdeveloperguide.lab.Department"></mapping> 
    </session-factory>
</hibernate-configuration>

In this hibernate.cnf.xml file we have configure the initial setup for db , and it will help us to interact with db using hibernate.

Department.java

package com.jdeveloperguide.lab;

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

@Entity
@Table(name="department")
public class Department {

    @Id
    @Column(name="deptid")
    private int deptid;
   
    private String deptname;
   
    public int getDeptid() {
        return deptid;
    }
    public void setDeptid(int deptid) {
        this.deptid = deptid;
    }
    public String getDeptname() {
        return deptname;
    }
    public void setDeptname(String deptname) {
        this.deptname = deptname;
    }
}
Here Department.java is the entity class which we are going to persist or save into db.We have used few annotation here like @Entity ,@Table , @Id , @Column , etc. This entity class looks like a helper class.

@Entity - This annotation will help you to define entity in RDBMS.

@Table - This annotation will help you to define a database table (entity) by specifying name.

 i.e. @Table(name="department").

@Id - This annotation will help you to define the id column , it means the primary key.

@Column - This annotation will help you to define the column name by specifying the column name. If your column name and java variable name are different the you can specify by name. In this example our database column name and variable name are same so, not required specify the column name. Hibernate will automatically match and take care this. But I have used because for better understanding.




Employee.java

package com.jdeveloperguide.lab;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name="employee")
public class Employee {

@Id   
@Column(name="empid")
private int empid;

@Column(name="empname")
private String empname;

@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="deptno")
private Department dept;

public int getEmpid() {
    return empid;
}

public void setEmpid(int empid) {
    this.empid = empid;
}

public String getEmpname() {
    return empname;
}

public void setEmpname(String empname) {
    this.empname = empname;
}

public Department getDept() {
    return dept;
}

public void setDept(Department dept) {
    this.dept = dept;
}   
}


 Here Employee.java is the entity class which we are going to persist or save into db along with Department.We have used few more new annotations here like @ManyToOne , @JoinColumn, etc.
Here we have mapped many-to-one , means many employee from one department.

@ManyToOne - Mapping many-to-one relation with hibernate.

@JoinColumn - This annotation is used for map the reference foreign key for any entity. This indicates the association with entity/table.

 CreateSessionFactory.java

package com.jdeveloperguide.lab;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

public class CreateSessionFactory {
    //Single point of access for SessionFactory
    private static final SessionFactory sessionFactory;
    static {
        try {
            //create sesson factory using the config file
            sessionFactory = new AnnotationConfiguration().configure("hibernate.cnf.xml").buildSessionFactory();
        } catch (Throwable ex) {
            throw new ExceptionInInitializerError(ex);
        }
    }
   
    //Static method for exposing the session
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

This class will help to create the SessionFactory object using .xml config file. This class having static method with we can call from any part of this application for getting SessionFactory object.Because , we will create Session object from SessionFactory

MainClass.java

package com.jdeveloperguide.lab;

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


public class MainClass {

    /**
     * @param args
     */
    public static void main(String[] args)throws Exception {
        MainClass mainObject=new MainClass();;
        Employee employee=new Employee();
        Department department=new Department();
        department.setDeptid(7);
        department.setDeptname("Computer Science");
       
        employee.setDept(department);
        employee.setEmpid(8);
        employee.setEmpname("Mr. JDeveloper");
        mainObject.saveEmployee(employee);
    }
   
    public void saveEmployee(Employee employee)throws Exception{
        Transaction transaction=null;
        Session session=null;
       
        try{
        //Create and open session
        session = CreateSessionFactory.getSessionFactory().openSession();
        //Create Transaction for maintain a user session
        transaction=session.beginTransaction();
        //Save the employee
        //Also it will save department ,because we have used cascade=CascadeType.ALL in employee
        session.save(employee);
        transaction.commit();
        }catch(HibernateException hibernateException){
            transaction.rollback();
            System.out.println("Error during save into DB :::"+hibernateException);
        }finally{
            session.close();
        }
    }
}

 This MainClass.java is the starting point of this example. Here we will execute our hibernate Many-to-One example and it will persist the data into DB.

Hibernate Generated SQL :-

Hibernate: select department_.deptid, department_.deptname as deptname1_ from department department_ where department_.deptid=?
Hibernate: insert into department (deptname, deptid) values (?, ?)
Hibernate: insert into employee (empname, deptno, empid) values (?, ?, ?)
When we will execute the MainClass.java class , it will generate these above queries by hibernate and these are auto generated. Its generating and showing because, we have mentioned in .xml config file show_sql is true.


Result in DB :-

Department Table











Employee Table






















Hope it will help you.














        

11 September, 2014

Singleton design pattern - A quick guide

Singleton design pattern is the most useful pattern in real time scenario.Singleton pattern will ensure that there is only one instance of a class is created in the JVM. This implementation restrict the user to create multiple access point or instance. This is a creational design pattern. It has many implementation over java language, but singleton is an anti-pattern or bad practice.



There is 2 basic way for implementing singleton behavior.

  • Eager/Early Loading
  • Lazy Loading

Eager/Early Loading


Eager/Early loading is basically load of objects before actually use. But, sometimes it’s not recommended, if the object creation is expensive.


A simple example of eager or early loading.



/**
 * Eager/Early Loading
 * @author javalang
 *
 */
public class SingleTon {

private static final SingleTon OBJSINGLETON=new SingleTon();

private SingleTon(){
      if(OBJSINGLETON!=null)
            throw new IllegalStateException("This is singleton, object already exist");
};

public static SingleTon getInstance(){
      return OBJSINGLETON;
}

}



Lazy Loading


Lazy loading means the object will be load when it’s required. When we need the object that time only we need to create object. It’s useful and recommended. But the use of singleton is depends on the context or requirement. It’s always recommended when the operation is really expensive.

A simple example of lazy loading.


package com.jdeveloperguide.lab;

/**
 * Lazy Loading
 * @author jdeveloperguide
 *
 */
public class SingleTon {

private static SingleTon OBJSINGLETON=null;

private SingleTon(){
      if(OBJSINGLETON!=null)
            throw newIllegalStateException("This is singleton, object already exist");
};

//Call this method & create object only when required
public static SingleTon getInstance(){
      if(OBJSINGLETON==null){
            OBJSINGLETON=new SingleTon();
      }
      return OBJSINGLETON;
}

}



But, in the above example the singleton object is not useful for multi-threaded 
environment. This above singleton objects are not thread safe. 
You can use ‘synchronized’ keyword to make the object creation thread safe.
 
A simple example with synchronized keyword.
 

package com.jdeveloperguide.lab;

/**
 * Lazy Loading
 * @author jdeveloperguide
 *
 */
public class SingleTon {

private static SingleTon OBJSINGLETON=null;

private SingleTon(){
      if(OBJSINGLETON!=null)
            throw newIllegalStateException("This is singleton, object already exist");
};

//Call this method & create object only when required
public static SingleTon getInstance(){
            synchronized (SingleTon.class) {
                  OBJSINGLETON=new SingleTon();
            }          
      return OBJSINGLETON;
}
} 




In the above example the synchronized block allow the object creation thread safe. But the member variable is not thread safe yet. The member variable OBJSINGLETON is not thread safe here. 


Here is one important question for interview. How to make a variable thread safe?


Ans : By using volatile keyword.



But, there is one another better approach which will help us to cross check the implementation. By implementing the “Double-checked locking” we can make the singleton object more secure. This ensure the expensive operation of creating object is the very first call. 

package com.jdeveloperguide.lab;

/**
 * Lazy Loading
 * @author jdeveloperguide
 *
 */
public class SingleTon {

private static volatile SingleTon OBJSINGLETON=null;

private SingleTon(){
      if(OBJSINGLETON!=null)
            throw newIllegalStateException("This is singleton, object already exist");
};

//Create object only when required
public static SingleTon getInstance(){
      //1st Check
      if(OBJSINGLETON==null){
            synchronized (SingleTon.class) {
                  //2nd Check
                  if(OBJSINGLETON==null)
                  OBJSINGLETON=new SingleTon();
            }          
      }
      return OBJSINGLETON;
}
}


Now the singleton object OBJSINGLETON is thread safe. But, there is one more issue with singleton when we go for serialization. Because, during deserialization process it creates new object and it violate the singleton strategy. So, we should make sure that there is no new objects are created during deserialization. To avoid this issue you can use readResolve() method in serializable.



A simple example using readResolve() method.

package com.jdeveloperguide.lab;

import java.io.Serializable;

/**
 * Lazy Loading
 * @author jdeveloperguide
 *
 */
public class SingleTon implements Serializable {

private static volatile SingleTon OBJSINGLETON=null;
public static final long serialVersionUID=0L;

private SingleTon(){
      if(OBJSINGLETON!=null)
            throw newIllegalStateException("This is singleton, object already exist");
};

//Create object only when required
public static SingleTon getInstance(){
      //2nd Check
      if(OBJSINGLETON==null){
            synchronized (SingleTon.class) {
                  //2nd Check
                  if(OBJSINGLETON==null)
                  OBJSINGLETON=new SingleTon();
            }          
      }
      return OBJSINGLETON;
}

//This ensure the protection on serialization
@SuppressWarnings("unused")
private SingleTon readResolve(){
      return OBJSINGLETON;
}
}


 All the above example with implementations are traditional , which are not recommended by java 5 and above. There is one more better way to implement singleton strategy by using Enum. A simple example below using Enum.


package com.jdeveloperguide.lab;

/**
 * Singleton behavior using Enum
 * @author jdeveloperguide
 *
 */
public enum SingleTonEnum {
SINGLETONINSTANCE;
public void javaProgrammingStuff(){
      //Here is your stuffs
}
}


Enum provides lazy loading approach. Enum gives guaranty for thread safety and safety during serialization.

 



               

Interview Questions :


Q – What is serialVersionUID ?

Ans :- This maintain version number in complied class. It’s useful during deserialization process. During deserialization it maintains the similar copy as similar as serialization process.


Q – What is readResolve() method ?

Ans :- This method ensure a unique object during deserialization. It’s useful when implementing serialization over singleton object. It avoid to create new object during deserialization.