Thursday, 26 July 2018

What is lazy loading in Hibernate? Explain with example

      In previous post, discussed the Hibernate JPA Cascade Types. In this post we can discuss the Lazy loading in Hibernate.

What is Lazy Loading in Hibernate ?


          Lazy setting decides whether to load child objects while loading the Parent Object. You need to specify parent class, Lazy = true in hibernate mapping file. Annotation based you can specify the FetchType.Lazy.
          Lazy loading means the child objects are not loaded unless they are explicitly invoked in the application by calling getChild() method on parent. In this case hibernate issues a fresh database call to load the child when getChild() is actully called on the Parent object. But in some cases you do need to load the child objects when parent is loaded. Just make the lazy=false and FetchType.EAGER(annotation based) and hibernate will load the child when parent is loaded from the database.

         The default fetch type depends on the type of the relationship. @ManyToOne and @OneToOne relationships have default FetchType.EAGER , @OneToMany and @ManyToMany relationships have default FetchType.LAZY.

Example:--

Employee.java
@Entity
@Table (name="employee")
public class Employee {
 
     @Id
     @Column(name="id")
     private int id;
 
     @Column(name="emp_name")
     private String name;
 
     @OneToMany(cascade=CascadeType.ALL, FetchType.LAZY) 
     @JoinColumn(name="address_id")
     private Set<Address> address;
       
        // setters and getters
}

            In the above example, Employee and Address entity have the One to Many relationship. The default fetch type of One to Many relationship is LAZY.

Address.java,

@Entity
@Table (name="address")
public class Address {
 
     @Id
     @Column(name="id")
     private int id;
 
     @Column(name="address")
     private String address;
       
        // setters and getters
}

Main Class,

HibernateMain.java,

package com.adnblog;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.adnblog.Employee;

public class HibernateMain {

      public static void main(String[] args) {

            SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
            Session session = sessionFactory.openSession();
            Transaction txn = session.beginTransaction();

            Employee emp = session.get(Employee.class, 1);   //check the below output
            System.out.println("Name:--"+emp.getName());
            Set<Address> addressSet = emp.getAddress();  
            tx.commit();                     
            sessionFactory.close();
      }
}

Output :--

select  employee0_.id as id1_0_0_, employee0_.name as name1_0_0_, employee0_.address as 
address2_0_0_  from Employee employee0_ where employee0_.id=?

Name:-- Kiran

select  employee0_.id as id1_0_0_,employee0_.name as name1_0_0_, employee1_.id as id2_0_0,  employee1_.address as 
address2_0_0_  from Employee employee0_  
join Address employee1_ where employee0_.id=?
         
          In the above output, when you will call getAddress() then only will hit the address table of database and bring the address details. Initially it won't hit the Address entity, it will return proxy object.

           Hibernate does not support lazy initialization for detached objects. Access to a lazy association outside of the context of an open Hibernate session will result in an LazyInitializationException.

Summary:--


        You can use the right FetchType for your use case to avoid common Hibernate performance issues.  For most of the use cases, the FetchType.LAZY is a good choice.

        FetchType.EAGER  of  Hibernate to fetch the related entities with the initial query. This can be very efficient because all entities are fetched with only one query. But in most cases it just creates a huge overhead because you select entities you don’t need in your use case.

        FetchType.LAZY of Hibernate to delay the initialization of the relationship until you access it in your business code. The drawback of this approach is that Hibernate needs to execute an additional query to initialize each relationship.


Thank you for visiting blog.


Related Posts:--

Thursday, 19 July 2018

Hibernate JPA Cascade Types

            In previous post, we learned the Difference between save() and persist() method in Hibernate. In this, we can discuss Cascade Types in Hibernate.

          The Hibernate JPA Cascade types are as follows,

  • PERSIST  ->  CascadeType.PERSIST  - save() or persist() operations cascade to related entities.
  • MERGE ->  CascadeType.MERGE -  related entities are merged when the owning entity is merged.
  • REFRESH ->  CascadeType.REFRESH - It is the same thing for the refresh() operation.
  • REMOVE ->  CascadeType.REMOVE -  removes all related entities association with this setting when the owning entity is delete.
  • DETACH - > CascadeType.DETACH - It detaches all related entities if a “manual detach” occurs.
  • ALL - > CascadeType.ALL - It is shorthand for all of the above cascade operations.


CascadeType.PERSIST


        CascadeType.PERSIST cascades the persist operation to all associated entities.  If we persist data in one entity then data will be saved in associated entity also. 
         For example if the entity Employee is associated with Address, if we are trying to save the data of Employee then it will save both parent(Employee) and the child entity(Address).  In Hibernate we need to call persist() method to persist the entity.

Employee.java

@Entity
@Table (name="employee")
public class Employee {
 
    @Id
    @Column(name="id")
    private int id;
 
    @Column(name="emp_name")
    private String name;
 
    @OneToMany(cascade=CascadeType.PERSIST) 
    @JoinColumn( name="address_id")
    private Set<Address> address;


    // setters and getters
}

Address.java


@Entity
@Table(name="address")
public class Address {
 
    @Id
    @Column(name="id")
    private int id;
 
    @Column(name="address_type")
    private String type;
  
    @column( name="address")
    private String address;

       
    // setters and getters
}

Below is the main Hibernate class to persist or save the above entities,

Address address = new Address();
address.setType("Permanent");
address.setAddress("At-Post-Sonyal, Sangli");

Employee emp = new Employee();
emp.setName("Kiran");
emp.setAddress(address);

session.persist(emp);  // will save both employee and address entities


CascadeType.MERGE

  
        CascadeType.MERGE cascades the merge operation to all associated entities.  If we merge data in one entity then data will be update in associated entity also.

Example:-

Employee.java,

@Entity
@Table (name="employee")
public class Employee {
 
     @Id
     @Column(name="id")
     private int id;
 
     @Column(name="emp_name")
     private String name;
 
     @OneToMany(cascade=CascadeType.MERGE) 
     @JoinColumn( name="address_id")
     private Set<Address> address;
       
     // setters and getters
}

Address Entity is as same as above in the example.

The Hibernate main class to merge the entities as below code,

Address address = new Address();
address.setType("Permanent");
address.setAddress("At-Post-Sonyal, Sangli");

Employee emp = new Employee();
emp.setName("Kiran");
emp.setAddress(address);

session.merge(emp);



CascadeType.REFRESH


         CascadeType.REFRESH cascades the refresh operation to all associated entities refresh by 
hibernate session. If one entity is refreshed, other associated entities will also be refreshed if CascadeType.REFRESH is annotated.

Example:-

Employee.java

@Entity
@Table (name="employee")
public class Employee {
 
     @Id
     @Column(name="id")
     private int id;
 
     @Column(name="emp_name")
     private String name;
 
     @OneToMany(cascade=CascadeType.REFRESH) 
     @JoinColumn( name="address_id")
     private Set<Address> address;
       
        // setters and getters
}

Address Entity is as same as above in the example.

Example of session Refresh() method:--


Address address = new Address();
address.setType("Permanent");
address.setAddress("At-Post-Sonyal, Sangli");

Employee emp = getEmployeeDetails();// getting existing employee details
emp.setAddress(address);

session.refresh(emp);

//here it will refresh the address in both tables


CascadeType.REMOVE


             CascadeType.REMOVE cascades the remove operation of entity from hibernate session to all associated entities remove. If one entity is removed, other associated entities will also be removed.
Example:--

Employee.java

@Entity
@Table (name="employee")
public class Employee {
 
     @Id
     @Column(name="id")
     private int id;
 
     @Column(name="emp_name")
     private String name;
 
     @OneToMany(cascade=CascadeType.REMOVE) 
     @JoinColumn( name="address_id")
     private Set<Address> address;
       
        // setters and getters
}

Address Entity is as same as above in the example.

Example of session remove() method:--


Employee emp = getEmployeeDetails();// getting existing employee details

session.delete(emp);

//here it will delete data in both tables


CascadeType.DETACH


         CascadeType.DETACH cascades the detach operation to all associated entities detach  from hibernate session. If one entity is detached, other associated entities will also be detached.
         For example if the entity Employee is associated with Address and we are detaching entity, both the entities Employee and Address will be detached from current session of hibernate. In Hibernate we need to call detach() method to detach the entity. 

Example:--

Employee.java,


@Entity
@Table (name="employee")
public class Employee {
 
     @Id
     @Column(name="id")
     private int id;
 
     @Column(name="emp_name")
     private String name;
 
     @OneToMany(cascade=CascadeType.DETACH) 
     @JoinColumn( name="address_id")
     private Set<Address> address;
       
        // setters and getters
}

Address Entity is as same as above in the example.

Use detach() method of session in Hibernate to detach the entity.


CascadeType.ALL


           In Hibernate there are different cascading PERSIST, MERGE, REMOVE, REFRESH, DETACH. These cascading are called by methods persist(), merge(), delete(), refresh(), detach(). In case we want to cascade in all above situation, then we need to use CascadeType.ALL. If we annotate our property in an entity by CascadeType.ALL, then for every action, cascading will be achieved. 

Example:--

Employee.java,

@Entity
@Table (name="employee")
public class Employee {
 
     @Id
     @Column(name="id")
     private int id;
 
     @Column(name="emp_name")
     private String name;
 
     @OneToMany(cascade=CascadeType.ALL) 
     @JoinColumn( name="address_id")
     private Set<Address> address;
       
        // setters and getters
}


Thanks for visiting blog......



Related Post:--
1) Difference between save() and persist() method in Hibernate
2) What is the difference between get() and load() methods in Hibernate?
3) Hibernate Criteria Queries and Examples
4) Hibernate Query Language(HQL) Examples
5) What is a Hibernate Caching ? Explain first level and second level cache in Hibernate
6) What are different states of an entity bean in Hibernate?

Sunday, 15 July 2018

Difference between save() and persist() method in Hibernate

           In previous post, we learned the difference between get() and load() methods in Hibernate. In this, we can discuss difference between the save() and persist() methods of Hibernate. This is one of the famous Hibernate interview question.

Difference between save() and persist() methods are as follows,

save and persist method in hibernate


save() method example:--


        The save() method which takes a transient object as input and put it to its persistent state. This method returns a generated identifier. 

package com.adnblog;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.adnblog.Employee;

public class HibernateSaveExample {

       public static void main(String[] args) {

             SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
             Session session = sessionFactory.openSession();
             Transaction txn = session.beginTransaction(); 

             Employee emp = new Employee();
             emp.setName("Mahesh");
             emp.setAddress("Sonyal");
  
             int id = (Integer) session.save(emp);   //save is called which will add this transient object to persistent state.
  
             txn.commit();                     
             sessionFactory.close();
      }
}


persist() method example:--


            In the same way persist() is another method to store objects in database i.e. changing transient objects to its persistent state. But persist() method does not return anything.

package com.adnblog;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.adnblog.Employee;

public class HibernatePersistentExample {

      public static void main(String[] args) {

            SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
            Session session = sessionFactory.openSession();
            Transaction txn = session.beginTransaction();

            Employee emp = new Employee();
            emp.setName("Mahesh");
            emp.setAddress("Sonyal");
  
            session.persist(emp);          //persist is called which will add this transient object to persistent state.
  
            tx.commit();                     
            sessionFactory.close();
      }
}

Thanks for visiting blog.....


Related Posts:--
1) What is the difference between get() and load() methods in Hibernate?
2) Hibernate Criteria Queries and Examples
3) Hibernate Query Language(HQL) Examples
4) What is a Hibernate Caching ? Explain first level and second level cache in Hibernate
5) What are different states of an entity bean in Hibernate?
6) Hibernate One to One Mapping Example - Annotation based
7) Hibernate - JPA Annotations with explanation
8) Advantages of Hibernate over JDBC

Saturday, 14 July 2018

What is the difference between get() and load() methods in Hibernate?

         In previous post, we learned the Hibernate Criteria API and it's example. In this, we can discuss difference between the get() and load() methods of Hibernate. This is one of the famous Hibernate interview question.

       In Hibernate Session, there are two methods for retrieving object from database i) get() and ii) load() method.  These two methods have been used in the different situations but both are from Session interface and we will call them as session.get() & session.load().

Session.load() method:


1) It will always return a proxy without hitting the database. In Hibernate, proxy is an object with   the given identifier value, its properties are not initialized yet, it just look like a temporary fake object.
2) load() method doesn’t hit the database.
3) If no row found , it will throws an ObjectNotFoundException.


Session.get() method:


1) It always hit the database and return the real object, an object that represent the database row, not proxy.
2) If no row found , it return null.
3) get() method always hit the database.
4) It returns real object not proxy.

get() method example:--


package com.adnblog;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import com.adnblog.HibernateUtil;

public class GetMethodHibernateExample {
    
     public static void main(String args[]) {
        
        //Create SessionFacctory
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
        
        //Create Session from SessionFactory
        Session session = sessionFactory.openSession();
        
        //Begin the transaction
        session.beginTransaction();
        
        //Create Employee object
        Employee employee = (Employee) session.get(Employee.class,new Integer(4322));
        System.out.println("Employee Details:--");
        System.out.println("Employee Id   : "+employee.getId());
        System.out.println("Employee Name : "+employee.getName());
        System.out.println("Employee Age  : "+employee.getAge());
        System.out.println("Department    : "+employee.getDept());
        
        //Commit the changes
        session.getTransaction().commit();
        //Close the session
        session.close();
    }
}


Output : -

Hibernate: select employee0_.id as id1_0_0_, employee0_.AGE as AGE2_0_0_, 
employee0_.DEPT as DEPT3_0_0_, employee0_.NAME as NAME4_0_0_ from EMPLOYEE employee0_ 
where employee0_.id=?
Employee Details
Employee Id   : 4322
Employee Name : JIP
Employee Age  : 100
Department    : IT

       In the above code, we have used session.get() to retrieve the employee with the ID 4322, Hibernate immediately hits the database and returns the original Employee object. This is the reason, we are getting the below SQL query immediately when we retrieve the employee id (employee.getId()).

Hibernate: select employee0_.id as id1_0_0_, employee0_.AGE as AGE2_0_0_, 
employee0_.DEPT as DEPT3_0_0_, employee0_.NAME as NAME4_0_0_ from EMPLOYEE employee0_ 
where employee0_.id=?


load() method example:-



package com.adnblog;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import com.adnblog.HibernateUtil;

public class loadMethodHibernateExample {
    
     public static void main(String args[]) {
        
        //Create SessionFacctory
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
        
        //Create Session from SessionFactory
        Session session = sessionFactory.openSession();
        
        //Begin the transaction
        session.beginTransaction();
        
        //Create Employee object
        Employee employee = (Employee) session.load(Employee.class,new Integer(4322));
        System.out.println("Employee Details:--");
        System.out.println("Employee Id   : "+employee.getId());
        System.out.println("Employee Name : "+employee.getName());
        System.out.println("Employee Age  : "+employee.getAge());
        System.out.println("Department    : "+employee.getDept());
        
        //Commit the changes
        session.getTransaction().commit();
        //Close the session
        session.close();
    }
}

Output :-
Employee Details:--
Employee Id   : 4322
Hibernate: select employee0_.id as id1_0_0_, employee0_.AGE as AGE2_0_0_, 
employee0_.DEPT as DEPT3_0_0_, employee0_.NAME as NAME4_0_0_ from EMPLOYEE employee0_
 where employee0_.id=?
Employee Name : JIP
Employee Age  : 100
Department    : IT

         In the above code, we have used session.load() to retrieve the employee with the ID 4322, Hibernate immediately created the fake Employee object with the Id 4322 and the remaining properties would not have been initialized.
         It will hit the database only when it tries to retrieve other properties of Employee object.



Related Posts:--
1)  Hibernate Criteria Queries and Examples
2) Hibernate Query Language(HQL) Examples
3) What is a Hibernate Caching ? Explain first level and second level cache in Hibernate
4) What are different states of an entity bean in Hibernate?
5) Hibernate One to One Mapping Example - Annotation based
6) Hibernate - JPA Annotations with explanation
7) Advantages of Hibernate over JDBC

Wednesday, 11 July 2018

Hibernate Criteria Queries and Examples

               In previous post, we learned the  Hibernate Query Language(HQL) Examples.  In this post, we will discuss about the Criteria API of hibernate & it's usage with examples.

There are three way to fetch the data from the database in the Hibernate.
  • Using Session Interface - get() and load() methods  -limited control to accessing data
  • Using HQL(Hibernate Query Language) – Slightly more control using where clause and other clauses but it is more complicated to maintain in case of bigger queries with lots of clauses.
  • Using Criteria API

What is Criteria API ?


          The API (Application Programming Interface) of Hibernate Criteria provides an elegant way
 of building dynamic query on the persistence database.

          The hibernate criteria API is very Simplified API for fetching data from Criterion objects. The criteria API is an alternative of HQL (Hibernate Query Language) queries.  It is more powerful and flexible for writing tricky criteria functions and dynamic queries.

         The Criteria API allows you to build up a criteria query object programmatically.  The org.hibernate.Criteria interface defines the available methods for one of these objects. The Hibernate Session interface contains several createCriteria() methods.  Pass the persistent object’s class or its entity name to the createCriteria() method and Hibernate will create a Criteria object that returns instances of the persistence object’s class when your application executes a criteria query.

Examples:-


          The below is the simple example of Criteria API with no any restrictions or no any optional parameters, it will return the all the data of that entity class.            

Criteria criteria = session.createCriteria(Employee.class);
List<Employee> results = criteria.list();

Next example, we will see some examples of Restrictions.

Using Restrictions with Criteria:-


           The Criteria API makes it easy to use restrictions in your queries to selectively retrieve objects. You can add restrictions to a Criteria object with the add() method. The add() method takes an org.hibernate.criterion.Criterion object that represents an individual restriction. You can have more than one restriction for a criteria query.

  • Restrictions.eq() Example
       To retrieve objects that have a property value that “equals” your restriction, use the eq() method on Restrictions, as follows:

Criteria criteria= session.createCriteria(Employee.class);
criteria.add(Restrictions.eq("name","Anil"));
List<Employee> results = criteria.list();

It will fetch all employee's having name with Anil.

  •  Restrictions.ne() Example

       To retrieve objects that have a property value “not equal to” your restriction, use the ne() method on Restrictions, as follows:

Criteria criteria= session.createCriteria(Employee.class);
criteria.add(Restrictions.ne("name","Anil"));
List<Employee> results = criteria.list()

It will fetch all employee's except name with Anil.

  •  Restrictions.like() and Restrictions.ilike() Example

         Using like() and ilike() method of Restrictions, we can retrieve all objects that have a property matching part of a given pattern. It's kind of like and ilike clause of SQL. The ilike() method is case-insensitive.

Criteria criteria= session.createCriteria(Employee.class);
criteria.add(Restrictions.like("name","Mahesh%",MatchMode.ANYWHERE));
List<Employee> results = criteria.list();

org.hibernate.criterion.MatchMode object to specify how to match the specified value to the stored data. The MatchMode object  has four different matches:

ANYWHERE: Anyplace in the string
END: The end of the string
EXACT: An exact match
START: The beginning of the string.


  • Restrictions.isNull() and Restrictions.isNotNull() Example

      The isNull() and isNotNull() method of Restrictions is to search the null and not null value of the property.

Criteria criteria= session.createCriteria(Employee.class);
criteria.add(Restrictions.isNull("name"));
List<Employee> results = criteria.list();

The isNotNull() is same like isNull() but it will return the property having not null values.


  •  Restrictions.gt(), Restrictions.ge(), Restrictions.lt() and Restrictions.le() Examples

          Several of the restrictions are useful for doing math comparisons. The greater-than comparison is gt(), the greater-than-or-equal-to comparison is ge(), the less-than comparison is lt(), and the less-than-or-equal-to comparison is le().

Criteria crt= session.createCriteria(Employee.class);
crt.add(Restrictions.gt("age", 40));
List<Employee> results = crt.list();


Paging Through the ResultSet:--


        In SQL query, we can use Offset and limit for pagination but in Criteria API have methods setFirstResult(int arg) and setMaxResults(int arg). Using these two methods we can construct paging component in our application.

Criteria criteria = session.createCriteria(Employee.class);
criteria.setFirstResult(1);
criteria.setMaxResults(20);
List<Employee> results = criteria.list();

The above query paginate 20 records each page, you can change this to 10 or 5 by setting setMaxResults to 10 or 5.


Obtaining a Unique Result:--

       
           If you want obtain a single Object reference instead of a List, the uniqueResult() method on the Criteria object returns an object or null. If there is more than one result, the uniqueResult() method throws a HibernateException.

        The following example demonstrates having a result set that would have included more than one result, except that it was limited with the setMaxResults() method,

Criteria criteria = session.createCriteria(Employee.class);
Criterion age = Restrictions.gt("age", 40);
criteria.setMaxResults(1);
Employee employee = (Employee) criteria.uniqueResult();


Obtaining Distinct Results:--


        Hibernate Criteria provides a result transformer for distinct entities, 
org.hibernate.transform.DistinctRootEntityResultTransformer, which ensures that no duplicates will be in your query’s result set. Rather than using SELECT DISTINCT with SQL, the distinct result transformer compares each of your results using their default hashCode() methods, and only adds those results with unique hash codes to your result set.

Criteria criteria = session.createCriteria(Employee.class);
Criterion age = Restrictions.gt("age", 40);
criteria.setResultTransformer( DistinctRootEntityResultTransformer.INSTANCE )
List<Employee> results = criteria.list();

Sorting the Query’s Results using Order:--


        Sorting the query’s results works much the same way with criteria as it would with HQL or SQL. The Criteria API provides the org.hibernate.criterion.Order class to sort your result set in either ascending or descending order, according to one of your object’s properties.

The below example demonstrates how to use the Order in Criteria,

Criteria crt = session.createCriteria(Employee.class);
crt.add(Restrictions.gt("age", 30));
crt.addOrder(Order.desc("age"));
List<Employee> results = crt.list();