Thursday, October 5, 2017

CyclicBarrier Real time Usage


In continuation to what we've learnt in CyclicBarrier , find below code snippet explaining real time scenario which is a perfect analogy.

package com.concurrent.jdk5;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/* 4 bikers starting from Manali and reaching to Leh after
 * crossing 3 checkpoints */
public class CyclicBarrierDemo {

     public static void main(String[] args) {
          final CyclicBarrier checkPoint = new CyclicBarrier(4, new BarrierAction());
    
          Thread t1 = new Thread(new Biker(checkPoint), "Biker 1");
          Thread t2 = new Thread(new Biker(checkPoint), "Biker 2");
          Thread t3 = new Thread(new Biker(checkPoint), "Biker 3");
          Thread t4 = new Thread(new Biker(checkPoint), "Biker 4");
          t1.start();
          t2.start();
          t3.start();
          t4.start();
     }
}

/* Worker thread*/
class Biker implements Runnable {

     private CyclicBarrier checkPoint;

     public Biker(CyclicBarrier checkPoint) {
          this.checkPoint = checkPoint;
         
     }

    
     public void run() {
          try {
              /* All bikers called await() and waiting to end the barrier. Once number of threads
               * crossing the barrier is equal to number mentioned in above construtor, then
               * last thread entering will call the barrier action which has seperate implementation*/
             
              System.out.println(Thread.currentThread().getName() + 
              " has left Manali");
              checkPoint.await();

              System.out.println(Thread.currentThread().getName() + 
              " has left the first checkpoint / barrier");

              /* Again, all bikers called await() and waiting to end the barrier. */
              checkPoint.await();
              System.out.println(Thread.currentThread().getName() + 
              " has left the second checkpoint / barrier");

              checkPoint.await();
              System.out.println(Thread.currentThread().getName() + 
           " has reached Leh");

          } catch (InterruptedException | BrokenBarrierException e) {
              e.printStackTrace();
          }
     }
}

/* barrierAction-the action to execute when all threads crossed the barrier number */
class BarrierAction implements Runnable {

     public void run() {
          System.out.println("Barrier Action run by Thread :"+Thread.currentThread().getName());
          System.out.println("\nAll bikers have arrived to checkpoint. Lets refill the petrol\n");
     }
}


Output

Biker 1 has left Manali
Biker 4 has left Manali
Biker 3 has left Manali
Biker 2 has left Manali
Barrier Action run by Thread :Biker 2

All bikers have arrived to checkpoint. Lets refill the petrol

Biker 2 has left the first checkpoint / barrier
Biker 3 has left the first checkpoint / barrier
Biker 1 has left the first checkpoint / barrier
Biker 4 has left the first checkpoint / barrier
Barrier Action run by Thread :Biker 4

All bikers have arrived to checkpoint. Lets refill the petrol

Biker 4 has left the second checkpoint / barrier
Biker 1 has left the second checkpoint / barrier
Biker 2 has left the second checkpoint / barrier
Biker 3 has left the second checkpoint / barrier
Barrier Action run by Thread :Biker 3

All bikers have arrived to checkpoint. Lets refill the petrol

Biker 3 has reached Leh
Biker 1 has reached Leh
Biker 2 has reached Leh
Biker 4 has reached Leh

References : http://codepumpkin.com/cyclicbarrier-java-concurrency-utilities/

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.