Showing posts with label Hibernate. Show all posts
Showing posts with label Hibernate. Show all posts

Tuesday, October 3, 2017

Important methods and there subtle difference in Hibernate

Save and Persist in Hibernate

save()-Save the given transient instance, first assigning a generated identifier. (Or using the current value of the identifier property if the assigned generator is used.)

Serializable org.hibernate.Session.save(Object object)
persist()-Make a transient instance persistent. This operation cascades to associated instances if the association is mapped with cascade="persist"
void org.hibernate.Session.persist(Object object)

public class HibernateSaveVsPersist {
    public static void main(String[] args) {

         SessionFactory sessionFactory =
         new Configuration().configure().buildSessionFactory();
         Session session = sessionFactory.openSession();

         session.beginTransaction();
         UserDetailsDTO user = new UserDetailsDTO();
         user.setUserName("Rahul");
         user.setAddress("Comviva A-26, Gurgaon");

        /* object a transient instance to persistent,return void*/
         session.persist(user);
        
       /* returns serializable object*/
         System.out.println(session.save(user));
         session.getTransaction().commit();
    }
}

Get and Load in Hibernate-

get() returns data either from first level cache or from Database where load() return proxy object and set ID to the proxy object.

When get() method is called no proxy object is created, hence it is called as early loading.

load() in hibernate



get() in hibernate



public
class HibernateGetVsLoad {
     public static void main(String[] args) {

          SessionFactory sessionFactory =
         new Configuration().configure().buildSessionFactory();
          Session session = sessionFactory.openSession();
          try {
              UserDetailsDTO user1 =
            (UserDetailsDTO) session.get(UserDetailsDTO.class, 11);
              System.out.println("Using get() " + user1);
          } catch (Exception e) {
              System.out.println("Exception thrown " + e);
          }

          try {
              UserDetailsDTO user2 =
           (UserDetailsDTO) session.load(UserDetailsDTO.class, 22);
              System.out.println("Using load() " + user2);
          } catch (Exception e) {
              System.out.println("Exception thrown " + e);
          }
     }
}

get() returns null when object doesn’t found whereas load() throw exception

Output :

Hibernate: select userdetail0_.USER_ID as USER_ID1_0_0_, userdetail0_.Address as Address2_0_0_, userdetail0_.createdOn as createdO3_0_0_, userdetail0_.description as descript4_0_0_, userdetail0_.USER_NAME as USER_NAM5_0_0_ from USER_DETAILS_NEW userdetail0_ where userdetail0_.USER_ID=?
Using get() null

Hibernate: select userdetail0_.USER_ID as USER_ID1_0_0_, userdetail0_.Address as Address2_0_0_, userdetail0_.createdOn as createdO3_0_0_, userdetail0_.description as descript4_0_0_, userdetail0_.USER_NAME as USER_NAM5_0_0_ from USER_DETAILS_NEW userdetail0_ where userdetail0_.USER_ID=?
Oct 03, 2017 5:26:19 PM org.hibernate.event.internal.DefaultLoadEventListener doOnLoad
INFO: HHH000327: Error performing load command : org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.hibernateInterviewQuestions.UserDetailsDTO#22]

Exception thrown org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.hibernateInterviewQuestions.UserDetailsDTO#22]

Merge and Update in hibernate

update() throws exception when object it is trying to update is already available in cache.

public class HibernateUpdateVsMerge {
    public static void main(String[] args) {
         SessionFactory sessionFactory =
         new Configuration().configure().buildSessionFactory();
         Session session = sessionFactory.openSession();

         UserDetailsDTO user =
         (UserDetailsDTO)session.get(UserDetailsDTO.class, 1);
         session.close();

         /* user object is in detached state now */
         user.setUserName("Merge Name-Paras");

         Session session2 = sessionFactory.openSession();
        
         /* A different object with the same identifier
         value was already associated with the session*/
        
         UserDetailsDTO user2 =
         (UserDetailsDTO)session2.get(UserDetailsDTO.class, 1);
        
         session2.beginTransaction();
         session2.update(user);
         session2.getTransaction().commit();
    }
}



Hibernate: select userdetail0_.USER_ID as USER_ID1_0_0_, userdetail0_.Address as Address2_0_0_, userdetail0_.createdOn as createdO3_0_0_, userdetail0_.description as descript4_0_0_, userdetail0_.USER_NAME as USER_NAM5_0_0_ from USER_DETAILS_NEW userdetail0_ where userdetail0_.USER_ID=?
Hibernate: select userdetail0_.USER_ID as USER_ID1_0_0_, userdetail0_.Address as Address2_0_0_, userdetail0_.createdOn as createdO3_0_0_, userdetail0_.description as descript4_0_0_, userdetail0_.USER_NAME as USER_NAM5_0_0_ from USER_DETAILS_NEW userdetail0_ where userdetail0_.USER_ID=?
Exception in thread "main" org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session

public class HibernateUpdateVsMerge {
    public static void main(String[] args) {
         SessionFactory sessionFactory =
         new Configuration().configure().buildSessionFactory();
         Session session = sessionFactory.openSession();

         UserDetailsDTO user =
         (UserDetailsDTO) session.get(UserDetailsDTO.class, 1);
         session.close();

         /* user object is in detached state now */
         user.setUserName("Merge Name-Paras");

         Session session2 = sessionFactory.openSession();
         UserDetailsDTO user2 =
         (UserDetailsDTO) session2.get(UserDetailsDTO.class, 1);
         session2.beginTransaction();
         session2.merge(user);
         session2.getTransaction().commit();
    }
}

merge() doesn’t throw exception. It verifies whether the same object is existed in cache or not. If object exists in cache, then changes are copied into cache else it will load the values to cache.

  

Wednesday, September 27, 2017

Methods in Hibernate

Session interface important methods get(),load(),evict(),update() and merge()

public class HibernateGetVsLoad {
     public static void main(String[] args) {

          SessionFactory sessionFactory =
     new Configuration().configure().buildSessionFactory();
          Session session = sessionFactory.openSession();

          UserDetailsDTO user1= (UserDetailsDTO) session.get(UserDetailsDTO.class, 1);
          System.out.println(user1.getUserName());
          System.out.println(user1.getAddress());
          System.out.println(user1.getDescription());
         
    
          UserDetailsDTO user2= (UserDetailsDTO) session.get(UserDetailsDTO.class, 1);
          System.out.println(user2.getUserName());
          System.out.println(user2.getAddress());
          System.out.println(user2.getDescription());
         
     }
}

Existing Database

select * from USER_DETAILS_NEW



Scenario 1: When Hibernate is using first level caching.

Output
Hibernate: select userdetail0_.USER_ID as USER_ID1_0_0_, userdetail0_.Address as Address2_0_0_, userdetail0_.createdOn as createdO3_0_0_, userdetail0_.description as descript4_0_0_, userdetail0_.USER_NAME as USER_NAM5_0_0_ from USER_DETAILS_NEW userdetail0_ where userdetail0_.USER_ID=?
Paras
722/18 Shastri Nagar , Rohtak
Hey ,Hibernate is Amazing
Paras
722/18 Shastri Nagar , Rohtak
Hey ,Hibernate is Amazing

Scenario 2: calling evict() and removing user1 object from cache

public class HibernateGetVsLoad {
     public static void main(String[] args) {

          SessionFactory sessionFactory =
     new Configuration().configure().buildSessionFactory();
          Session session = sessionFactory.openSession();

          UserDetailsDTO user1= (UserDetailsDTO) session.get(UserDetailsDTO.class, 1);
          System.out.println(user1.getUserName());
          System.out.println(user1.getAddress());
          System.out.println(user1.getDescription());
         
          session.evict(user1);
          //session.clear();
          //session.flush();
         
          UserDetailsDTO user2= (UserDetailsDTO) session.get(UserDetailsDTO.class, 1);
          System.out.println(user2.getUserName());
          System.out.println(user2.getAddress());
          System.out.println(user2.getDescription());
         
     }
}

Output

Hibernate: select userdetail0_.USER_ID as USER_ID1_0_0_, userdetail0_.Address as Address2_0_0_, userdetail0_.createdOn as createdO3_0_0_, userdetail0_.description as descript4_0_0_, userdetail0_.USER_NAME as USER_NAM5_0_0_ from USER_DETAILS_NEW userdetail0_ where userdetail0_.USER_ID=?
Paras
722/18 Shastri Nagar , Rohtak
Hey ,Hibernate is Amazing

Hit Again to Database

Hibernate: select userdetail0_.USER_ID as USER_ID1_0_0_, userdetail0_.Address as Address2_0_0_, userdetail0_.createdOn as createdO3_0_0_, userdetail0_.description as descript4_0_0_, userdetail0_.USER_NAME as USER_NAM5_0_0_ from USER_DETAILS_NEW userdetail0_ where userdetail0_.USER_ID=?
Paras
722/18 Shastri Nagar , Rohtak
Hey ,Hibernate is Amazing

Scenario 3 calling session.clear(); clears everything within a session

Hibernate: select userdetail0_.USER_ID as USER_ID1_0_0_, userdetail0_.Address as Address2_0_0_, userdetail0_.createdOn as createdO3_0_0_, userdetail0_.description as descript4_0_0_, userdetail0_.USER_NAME as USER_NAM5_0_0_ from USER_DETAILS_NEW userdetail0_ where userdetail0_.USER_ID=?
Paras
722/18 Shastri Nagar , Rohtak
Hey ,Hibernate is Amazing

Hit Again to Database

Hibernate: select userdetail0_.USER_ID as USER_ID1_0_0_, userdetail0_.Address as Address2_0_0_, userdetail0_.createdOn as createdO3_0_0_, userdetail0_.description as descript4_0_0_, userdetail0_.USER_NAME as USER_NAM5_0_0_ from USER_DETAILS_NEW userdetail0_ where userdetail0_.USER_ID=?
Paras
722/18 Shastri Nagar , Rohtak
Hey ,Hibernate is Amazing

Scenario 4 – When Id doesn’t exist and we’re calling session.get()

UserDetailsDTO user1= (UserDetailsDTO) session.get(UserDetailsDTO.class, 1);                                   
UserDetailsDTO user2= (UserDetailsDTO) session.get(UserDetailsDTO.class, 3);
Output
Hibernate: select userdetail0_.USER_ID as USER_ID1_0_0_, userdetail0_.Address as Address2_0_0_, userdetail0_.createdOn as createdO3_0_0_, userdetail0_.description as descript4_0_0_, userdetail0_.USER_NAME as USER_NAM5_0_0_ from USER_DETAILS_NEW userdetail0_ where userdetail0_.USER_ID=?
Paras
722/18 Shastri Nagar , Rohtak
Hey ,Hibernate is Amazing
Hibernate: select userdetail0_.USER_ID as USER_ID1_0_0_, userdetail0_.Address as Address2_0_0_, userdetail0_.createdOn as createdO3_0_0_, userdetail0_.description as descript4_0_0_, userdetail0_.USER_NAME as USER_NAM5_0_0_ from USER_DETAILS_NEW userdetail0_ where userdetail0_.USER_ID=?
Exception in thread "main" java.lang.NullPointerException
 at com.hibernateInterviewQuestions.HibernateGetVsLoad.main(HibernateGetVsLoad.java:23)

Scenario 5: get() and load() when entry doesn’t exist

public class HibernateGetVsLoad {
     public static void main(String[] args) {

          SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
          Session session = sessionFactory.openSession();
          try {
              UserDetailsDTO user1 = (UserDetailsDTO) session.get(UserDetailsDTO.class, 3);
              System.out.println("Using get() "+user1);
          } catch (Exception e) {
              System.out.println("Exception thrown " +e);
          }

          try {
              UserDetailsDTO user2 = (UserDetailsDTO) session.load(UserDetailsDTO.class, 3);
              System.out.println("Using load() "+user2);
          } catch (Exception e) {
              System.out.println("Exception thrown " +e);
          }

     }
}

Output
Hibernate: select userdetail0_.USER_ID as USER_ID1_0_0_, userdetail0_.Address as Address2_0_0_, userdetail0_.createdOn as createdO3_0_0_, userdetail0_.description as descript4_0_0_, userdetail0_.USER_NAME as USER_NAM5_0_0_ from USER_DETAILS_NEW userdetail0_ where userdetail0_.USER_ID=?

Using get() null

Hibernate: select userdetail0_.USER_ID as USER_ID1_0_0_, userdetail0_.Address as Address2_0_0_, userdetail0_.createdOn as createdO3_0_0_, userdetail0_.description as descript4_0_0_, userdetail0_.USER_NAME as USER_NAM5_0_0_ from USER_DETAILS_NEW userdetail0_ where userdetail0_.USER_ID=?

Exception thrown org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.hibernateInterviewQuestions.UserDetailsDTO#3]

Difference between get() and load()

1. Behavior when Object is not found in Session Cache
Apart from performance this is another difference between get and load which is worth remembering. get method of Hibernate Session class returns null if object is not found in cache as well as on database while load() method throws ObjectNotFoundException if object is not found on cache as well as on database but never return null.

2. Database hit
Get method always hit database while load() method may not always hit the database, depending upon which method is called.

3. Proxy
Get method never returns a proxy, it either returns null or fully initialized Object, while load() method may return proxy, which is the object with ID but without initializing other properties, which is lazily initialized. If you are just using returned object for creating relationship and only need Id then load() is the way to go.

4. Performance
By far most important difference between get and load in my opinion. get method will return a completely initialized object if  Object is not on the cache but exists on Database, which may involve multiple round-trips to database based upon object relational mappings while load() method of Hibernate can return a proxy which can be initialized on demand (lazy initialization) when a non identifier method is accessed. Due to above reason use of load method will result in slightly better performance, but there is a caveat that proxy object will throw ObjectNotFoundException later if corresponding row doesn’t exists in database, instead of failing immediately so not a fail fast behavior.

5. load method exists prior to get method which is added on user request.