Thursday, 24 April 2014

How HashMap works in Java

Hashing :How hash map works in java or How get() method works internally
One of the most darling question of the core java interviewers is How hash map works in java or internal.implementation of hashmap. Most of the candidates rejection chances increases if the candidate do not give the satisfactory explanation . This question shows that candidate has good knowledge of Collection . So this question should be in your to do list before appearing for the interview .

Read also  How Hashset works in java or How it ensures uniqueness in java 

How Hashmap works in Java

HashMap works on the principle of Hashing .  To understand Hashing , we should understand the three terms first   i.e  Hash Function , Hash Value and Bucket .

What is Hash Function , Hash Value  and Bucket ?

hashCode() function  which returns an integer value is the Hash function. The important point to note that ,  this method is present in Object class ( Mother of all class ) .

This is the code for the hash function(also known as hashCode method) in Object Class :

    public native int hashCode();

The most important point to note from the above line :  hashCode method return  int value .
So the Hash value is the int value returned by the hash function .


    So summarize the terms in the diagram below :
                

how hash  map works in java









What is bucket ?
A bucket is used to store key value pairs . A bucket can have multiple key-value pairs . In hash map, bucket used simple linked list to store objects .

After understanding the terms we are ready to move next step , 
How hash map works in java or How get() works internally in java .



Code inside Java Api (HashMap class internal implementation) for HashMap get(Obejct key) method 
1.  Public  V get(Object key)
   {
2.     if (key ==null)
3.     //Some code
   
4.     int hash = hash(key.hashCode());
   
5.     // if key found in hash table then  return value
6.     //    else return null
   }

Hash map works on the principle of hashing 

HashMap get(Key k) method calls hashCode method on the key object and applies returned hashValue to its own static hash function to find a bucket location(backing array) where keys and values are stored in form of anested class called Entry (Map.Entry) . So you have concluded that from the previous line that Both key and value is stored in the bucket as a form of  Entry object . So thinking that Only value is stored  in the bucket is not correct and will not give a good impression on the interviewer .

* Whenever we call get( Key k )  method on the HashMap object . First it checks that whether key is null or not .  Note that there can only be one null key in HashMap .  

If key is null , then Null keys always map to hash 0, thus index 0.


If key is not null then , it will call hashfunction on the key object , see line 4 in above method i.e. key.hashCode()  ,so after key.hashCode() returns hashValue , line 4 looks like

4.                int hash = hash(hashValue)

 , and now ,it applies returned hashValue into its own hashing function .

We might wonder why we are calculating the hashvalue again using hash(hashValue). Answer is ,It defends against poor quality hash functions.

Now step 4 final  hashvalue is used to find the bucket location at which the Entry object is stored . Entry object stores in the bucket like this (hash,key,value,bucketindex) .  

Interviewer:    What if  when two different keys have the same hashcode ?

Solution, equals() method comes to rescue.Here candidate gets puzzled. Since bucket is one and we have two objects with the same hashcode .Candidate usually forgets that bucket is a simple linked list.

The bucket is the linked list effectively . Its not a LinkedList as in a java.util.LinkedList - It's a separate (simpler) implementation just for the map .

So we traverse through linked list , comparing keys in each entries using keys.equals() until it return true.  Then the corresponding entry object Value is returned .

how hashmap works internally in java








When the functions 'equals' traverses through the linked list does it traverses from start to end one by one...in other words brute method. Or the linked list is sorted based on key and then it traverses? 

Answer is when an element is added/retrieved, same procedure follows:

 
a. Using key.hashCode() [ see above step 4],determine initial hashvalue for the key

b. Pass intial hashvalue as hashValue  in    hash(hashValue) function, to calculate the final hashvalue.

c. Final hash value is then passed as a first parameter in the indexFor(int ,int )method .
    The second parameter is length which is a constant in HashMap Java Api , represented by                             DEFAULT_INITIAL_CAPACITY

    The default  value of DEFAULT_INITIAL_CAPACITY is 16 in HashMap Java Api .

 indexFor(int,int) method  returns the first entry in the appropriate bucket. The linked list in the bucket is then iterated over - (the end is found and the element is added or the key is matched and the value is returned )


Explanation about indexFor(int,int) is below :
/**
* Returns index for hash code h.
*/
static int indexFor(int h, int length) {
    return h & (length-1);
}


The above function indexFor() works because Java HashMaps always have a capacity, i.e. number of buckets, as a power of 2.
 Let's work with a capacity of 256,which is 0x100, but it could work with any power of 2. Subtracting 1
from a power of 2 yields the exact bit mask needed to bitwise-and with the hash to get the proper bucket index, of range 0 to length - 1.
256 - 1 = 255
0x100 - 0x1 = 0xFF
E.g. a hash of 257 (0x101) gets bitwise-anded with 0xFF to yield a bucket number of 1.



Interviewer:    What if  when two  keys are same and have the same hashcode ?
If key needs to be inserted and already inserted hashkey's hashcodes are same, and keys are also same(via reference or using equals() method)  then override the previous key value pair with the current key value pair.

The other important point to note is that in Map ,Any class(String etc.) can serve as a key if and only if it overrides the equals() and hashCode() method .


Interviewer:  How will you measure the performance of HashMap?


According to Oracle Java docs,

An instance of HashMap has two parameters that affect its performance: initial capacity and load factor.

The capacity is the number of buckets in the hash table( HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.), and the initial capacity is simply the capacity at the time the hash table is created.


The load factor is a measure of how full the hash table is allowed to get before its capacity is automatically increased. When the number of entries in the hash table exceeds the product of the load factor and the current capacity, the hash table is rehashed (that is, internal data structures are rebuilt) so that the hash table has approximately twice the number of buckets.

In HashMap class, the default value of load factor is (.75) .


If you still have any doubts then please write in comments .
Source of image : http://ru.wikipedia.org
 Source content:  http://javahungry.blogspot.com/2013/08/hashing-how-hash-map-works-in-java-or.html


Tuesday, 22 April 2014

Hibernate Interview Questions

1.What is the general flow of Hibernate communication with RDBMS?
The general flow of Hibernate communication with RDBMS is :
  • Load the Hibernate configuration file and create configuration object. It will automatically load all hbm mapping files
  • Create session factory from configuration object
  • Get one session from this session factory
  • Create HQL Query
  • Execute query to get list containing Java objects


2.What are the types of inheritance models in Hibernate?
There are three types of inheritance models in Hibernate:
  • Table per class hierarchy
  • Table per subclass
  • Table per concrete class


3.What do you mean by Named – SQL query?
Named SQL queries are defined in the mapping xml document and called wherever required.
Example:
<sql-query name = "empdetails">
   <return alias="emp" class="com.test.Employee"/>
      SELECT emp.EMP_ID AS {emp.empid},
                 emp.EMP_ADDRESS AS {emp.address},
                 emp.EMP_NAME AS {emp.name} 
      FROM Employee EMP WHERE emp.NAME LIKE :name
</sql-query>

Invoke Named Query :
List people = session.getNamedQuery("empdetails")
       .setString("TomBrady", name)
       .setMaxResults(50)
       .list();
 Named queries are SQL queries which are defined in mapping document using <sql-query> tag and called using Session.getNamedQuery() method. Named query allows you to refer a particular query by the name you provided, by the way you can define named query in hibernate either by using annotations or xml mapping file, as I said above. @NameQuery is used to define single named query and @NameQueries is used to define multiple named query in hibernate.


4.What is difference between get and load method in Hibernate?
1. session.load()
·         It will always return a “proxy” (Hibernate term) 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.
·         If no row found , it will throws an ObjectNotFoundException.
2. session.get()
·         It always hit the database and return the real object, an object that represent the database row, not proxy.
·         If no row found , it return null.
It’s about performance
Hibernate create anything for some reasons, when you do the association, it’s normal to obtain retrieve an object (persistent instance) from database and assign it as a reference to another object, just to maintain the relationship. Let’s go through some examples to understand in what situation you should use session.load().
1. session.get()
For example, in a Stock application , Stock and StockTransactions should have a “one-to-many” relationship, when you want to save a stock transaction, it’s common to declared something like below
                       Stock stock = (Stock)session.get(Stock.class, new Integer(2));
           StockTransaction stockTransactions = new StockTransaction();
           //set stockTransactions detail
           stockTransactions.setStock(stock);       
           session.save(stockTransactions);
Output
Hibernate:
    select ... from mkyong.stock stock0_
    where stock0_.STOCK_ID=?
Hibernate:
    insert into mkyong.stock_transaction (...)
    values (?, ?, ?, ?, ?, ?)
In session.get(), Hibernate will hit the database to retrieve the Stock object and put it as a reference to StockTransaction. However, this save process is extremely high demand, there may be thousand or million transactions per hour, do you think is this necessary to hit the database to retrieve the Stock object everything save a stock transaction record? After all you just need the Stock’s Id as a reference to StockTransaction.
2. session.load()
In above scenario, session.load() will be your good solution, let’s see the example,
                       Stock stock = (Stock)session.load(Stock.class, new Integer(2));
           StockTransaction stockTransactions = new StockTransaction();
           //set stockTransactions detail
           stockTransactions.setStock(stock);       
           session.save(stockTransactions);
Output
Hibernate:
    insert into mkyong.stock_transaction (...)
    values (?, ?, ?, ?, ?, ?)
In session.load(), Hibernate will not hit the database (no select statement in output) to retrieve the Stock object, it will return a Stock proxy object – a fake object with given identify value. In this scenario, a proxy object is enough for to save a stock transaction record.
Exception
In exception case, see the examples
session.load()
Stock stock = (Stock)session.load(Stock.class, new Integer(100)); //proxy

 //initialize proxy, no row for id 100, throw ObjectNotFoundException
System.out.println(stock.getStockCode());
It will always return a proxy object with the given identity value, even the identity value is not exists in database. However, when you try to initialize a proxy by retrieve it’s properties from database, it will hit the database with select statement. If no row is found, a ObjectNotFoundException will throw.
org.hibernate.ObjectNotFoundException: No row with the given identifier exists:
[com.mkyong.common.Stock#100]
session.get()
//return null if not found
Stock stock = (Stock)session.get(Stock.class, new Integer(100));
System.out.println(stock.getStockCode()); //java.lang.NullPointerException
It will always return null , if the identity value is not found in database.

5.What is hibernate caching and different types of it?

Fist level cache in hibernate is enabled by default and you do not need to do anything to get this functionality working. In fact, you can not disable it even forcefully.
Its easy to understand the first level cache if we understand the fact that it is associated with Session object. As we know session object is created on demand from session factory and it is lost, once the session is closed. Similarly, first level cache associated with session object is available only till session object is live. It is available to session object only and is not accessible to any other session object in any other part of application.
//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Session sessionTemp = HibernateUtil.getSessionFactory().openSession();
sessionTemp.beginTransaction();
try
{
    //fetch the department entity from database first time
    DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.classnew Integer(1));
    System.out.println(department.getName());
     
    //fetch the department entity again
    department = (DepartmentEntity) session.load(DepartmentEntity.classnew Integer(1));
    System.out.println(department.getName());
     
    department = (DepartmentEntity) sessionTemp.load(DepartmentEntity.classnew Integer(1));
    System.out.println(department.getName());
}
finally
{
    session.getTransaction().commit();
    HibernateUtil.shutdown();
     
    sessionTemp.getTransaction().commit();
    HibernateUtil.shutdown();
}
Output:
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
Human Resource
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource



  • Second level cache: 
Above statement means, second level cache is created in session factory scope and is available to be used in all sessions which are created using that particular session factory.
It also means that once session factory is closed, all cache associated with it die and cache manager also closed down.

Configuring EhCache

To configure ehcache, you need to do two steps:
  1. configure Hibernate for second level caching
  2. specify the second level cache provider
Hibernate 3.3 and above
?
1
2
<property key="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</property>
Hibernate 3.2 and below
?
1
2
<property key="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.region.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</property>

Configuring entity objects

This may done in two ways.
1) If you are using hbm.xml files then use below configuration:
?
1
2
3
<class name="com.application.entity.DepartmentEntity" table="...">
    <cache usage="read-write"/>
</class>
2) Otherwise, if you are using annotations, use these annotations:
?
1
2
3
4
5
6
7
@Entity
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY,
region="department")
public class DepartmentEntity implements Serializable
{
    //code
}
For both options, caching strategy can be of following types:
  • none : No caching will happen.
  • read-only : If your application needs to read, but not modify, instances of a persistent class, a read-only cache can be used.
  • read-write : If the application needs to update data, a read-write cache might be appropriate.
  • nonstrict-read-write : If the application only occasionally needs to update data (i.e. if it is extremely unlikely that two transactions would try to update the same item simultaneously), and strict transaction isolation is not required, a nonstrict-read-write cache might be appropriate.
  • transactional : The transactional cache strategy provides support for fully transactional cache providers such as JBoss TreeCache. Such a cache can only be used in a JTA environment and you must specify hibernate.transaction.manager_lookup_class.

5.What is difference between Update() and merge() method in Hibernate?


Update():- if you are sure that the session does not contains an already persistent instance with the same identifier then use update to save the data in hibernate
Merge():-if you want to save your modificatiions at any time with out knowing abot the state of an session then use merge() in hibernate.

SessionFactory sf =         ctx.getBean("hibernateSessionFactory",SessionFactory.class);
Session session = sf.openSession();
Transaction t = session.beginTransaction();
try {
   Session s2 = sf.openSession();
    Organization org = (Organization)s2.get(Organization.class,100624l);//1
    org.setOrgName("org");
    s2.close();//2
   Organization org1 =  (Organization)session.get(Organization.class,100624l);//3
    org.setOrgName("testOrg");
   org1.setOrgName("org");//a
    session.merge(org);//4
    System.out.println(org == org1);//b 
     t.commit();
} catch (HibernateException e) {
  t.rollback();
  throw e;
}finally{
      session.close();
 }


  1. 1st instance is loaded and made persistent.
  2. The instance is detached.
  3. Another instance is loaded
  4. At the point of executing this operation, there are 2 instances of the same object in the session(org and org1) – org is detached and org1 is persistent If we do an update() or saveOrUpdate() there, we get the below exception:
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.spring.model.Organization#100624]
a. We do a merge here which:
I. Merges the state of the detached object + persistent object.
II. In case of conflict, the object which is merged wins, like in this case, the value saved will be : testOrg
III. Had we merged on org1, we would have got org.
b. This will always return false, meaning post merge, org was still in DETACHED state
I hope the diff. is clear now.
Summary : saveOrUpdate() or update() will throw an exception if there are 2 instances of the same object in the session(one detached and one persistent)
merge() will not throw the exception, but will save the object while merging the changes.
6.What is difference between update() and saveorUpdate() method in Hibernate?
save
Save method stores an object into the database. That means it insert an entry if the identifier doesn’t exist, else it will throw error. If the primary key already present in the table, it cannot be inserted.
update
Update method in the hibernate is used for updating the object using identifier. If the identifier is missing or doesn’t exist, it will throw exception.
saveOrUpdate
This method calls save() or update() based on the operation. If the identifier exists, it will call update method else the save method will be called. saveOrUpdate() method does the following:
  • If the object is already persistent in the current session, it do nothing
  • If another object associated with the session has the same identifier, throw an exception to the caller
  • If the object has no identifier property, save() the object
  • If the object’s identifier has the value assigned to a newly instantiated object, save() the object.

1 package hibernate;
2import org.hibernate.Session;
3import org.hibernate.SessionFactory;
4import org.hibernate.Transaction;
5import org.hibernate.cfg.Configuration;
6
7/**
8 * source : www.javabeat.net
9 */
10public class HibernateExample {
11    public static void main(String args[]){
12    Configuration configuration = new Configuration();
13    SessionFactory  sessionFactory =
14           configuration.configure().buildSessionFactory();
15    Session session = sessionFactory.openSession();
16    Transaction transaction = session.beginTransaction();
17    transaction.begin();
18    EmployeeInfo employeeInfo = new EmployeeInfo();
19    employeeInfo.setSno(1);
20    employeeInfo.setName("HibernateTestSave");
21    session.save(employeeInfo);
22    transaction.commit();
23    session.close();
24
25    session = sessionFactory.openSession();
26    transaction = session.beginTransaction();
27    transaction.begin();
28    employeeInfo = new EmployeeInfo();
29    employeeInfo.setSno(1);
30    employeeInfo.setName("HibernateTestUpdate");
31    session.update(employeeInfo);
32    transaction.commit();
33    session.close();
34
35    session = sessionFactory.openSession();
36
37    transaction = session.beginTransaction();
38    transaction.begin();
39    employeeInfo = new EmployeeInfo();
40    employeeInfo.setSno(1);
41    employeeInfo.setName("HibernateTestSaveOrUpdate");
42    session.saveOrUpdate(employeeInfo);
43    transaction.commit();
44
45    session.close();
46   }
47}
- Source at: http://www.javabeat.net/difference-between-hibernates-saveupdate-and-saveorupdate-methods

6.Why Hibernate has no args constructor.

The hibernate is an ORM framework which supports field or property access strategy. However, it does not support constructor-based mapping - maybe what you would like ? - because of some issues like
 What happens whether your class contains a lot of constructors
public class Person {

    private String name;
    private Integer age;

    public Person(String name, Integer age) { ... }
    public Person(String name) { ... }
    public Person(Integer age) { ... }

}
As you can see, you deal with a issue of inconsistency because Hibernate cannot suppose which constructor should be called. For instance, suppose you need to retrieve a stored Person object
Person person = (Person) session.get(Person.class, <IDENTIFIER>);
Which constructor should Hibernate call to retrieve a Person object ? Can you see ?
 And finally, by using reflection, Hibernate can instantiate a class through its no-arg constructor. So when you call
Person person = (Person) session.get(Person.class, <IDENTIFIER>);
Hibernate will instantiate your Person object as follows
Person.class.newInstance();
Which according to API documentation
The class is instantiated as if by a new expression with an empty argument list
Moral of the story
Person.class.newInstance();
is similar To
new Person();
Nothing else
http://stackoverflow.com/questions/2935826/why-does-hibernate-require-no-argument-constructor

7.What are different states in Hibernate


1. Transient State:
    A New instance of  a persistent class which is not associated with a Session, has no representation in the database and no identifier value is considered transient by Hibernate:
UserDetail user = new UserDetail();
user.setUserName("Dinesh Rajput");
// user is in a transient state
2. Persistent State:
    A persistent instance has a representation in the database , an identifier value and is associated with a Session. You can make a transient instance persistent by associating it with a Session:
Long id = (Long) session.save(user);
// user is now in a persistent state
3. Detached State:
    Now, if we close the Hibernate Session, the persistent instance will become a detached instance: it isn't attached to a Sessionanymore (but can still be modified and reattached to a new Session later though).
session.close();
//user in detached state
Difference between Transient and Detached States:
Transient objects do not have association with the databases and session objects. They are simple objects and not persisted to the database. Once the last reference is lost, that means the object itself is lost. And of course , garbage collected. The commits and rollbacks will have no effects on these objects. They can become into persistent objects through the save method calls of Session object.

The detached object have corresponding entries in the database. These are persistent and not connected to the Session object. These objects have the synchronized data with the database when the session was closed. Since then, the change may be done in the database which makes this object stale. The detached object can be reattached after certain time to another object in order to become persistent again.

Lets see in the following example to save or update the user data...
package com.sdnext.hibernate.tutorial;

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

import com.sdnext.hibernate.tutorial.dto.UserDetails;

public class HibernateTestDemo {
 /**
  * @param args
  */
 public static void main(String[] args) 
 {
  UserDetails userDetails = new UserDetails();
                userDetails.setUserName("Dinesh Rajput");
                userDetails.setAddress("Noida City");
  //Here 'userDetails' is TRANSIENT object
  
                SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
  Session session = sessionFactory.openSession();
  session.beginTransaction();
  
   session.save(userDetails);
  //Here 'userDetails' is PERSISTENT object
   userDetails.setUserName("User Updated after session close");

                session.getTransaction().commit();
  session.close();
  //Here 'userDetails' is DETACHED object
 }
}







http://www.dineshonjava.com/p/transient-persistent-and-detached.html#.U_IiAPmSwSk