This has to be one of the most popular questions asked in hibernate interviews:
What is the difference between get() and load() method ?
Hibernate provides us with the two methods to load a persistent entity from the database. These signatures are session.get(Class, Serializable) and session.load(Class, Serializable). Both methods take a class variable and an identifier object and return an instance of the Entity class.
The most common answer that people (including me before I learned this) give is :
If the entity is not found in the database, get() will return null while load() will throw an Hibernate exception.
But why ? Hibernate wouldn't provide two methods that did the same action but would be distinguished by their handling of missing rows ? Or is that the case ?
The real difference is that the get() method actually loads and returns the record from the database whereas the load() method only returns a proxy.
In fact if the above code is executed with an id 999 (record does not exist), the code will still work fine.Hibernate does not throw any exception.As there has been no database hit, Hibernate very happily creates a proxy with the id 999.What is the difference between get() and load() method ?
Hibernate provides us with the two methods to load a persistent entity from the database. These signatures are session.get(Class, Serializable) and session.load(Class, Serializable). Both methods take a class variable and an identifier object and return an instance of the Entity class.
The most common answer that people (including me before I learned this) give is :
If the entity is not found in the database, get() will return null while load() will throw an Hibernate exception.
But why ? Hibernate wouldn't provide two methods that did the same action but would be distinguished by their handling of missing rows ? Or is that the case ?
The real difference is that the get() method actually loads and returns the record from the database whereas the load() method only returns a proxy.
static void checkDifference() { Session session = sessionFactory.openSession(); Entity entity1 = (Entity) session.load(Entity.class, 1); System.out.println("Entity 1: " + entity1.getClass()); Entity entity2 = (Entity) session.get(Entity.class, 2); System.out.println("Entity 2: " + entity2.getClass()); }The console displays the class types:
Entity 1: class com.model.Entity$$EnhancerByCGLIB$$b82499d4 Entity 2: class com.model.EntityThe logs indicate that for the get call:
- Hibernate fired a select query and fetched the record from the database.
- It then added the object to the persistence cache.
- Hibernate creates a proxy object and no select query is fired.
- As no data was fetched no insertions are performed in the persistence cache.
However if we try to access one of the fields using a getter call then:
static void checkDifference() { Session session = sessionFactory.openSession(); Entity entity1 = (Entity) session.load(Entity.class, 999); System.out.println("hashcode is " + entity1.hashCode()); System.out.println("equals is " + entity1.equals(new Entity())); System.out.println("The data is " + entity1); }Even a simple toString call results in the below error.
hashcode is 4815156 equals is false Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with th e given identifier exists: [com.model.Entity#999] at org.hibernate.impl.SessionFactoryImpl$1.handleEntityNotFound(SessionFactoryI mpl.java:377) at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyIni tializer.java:79) at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializ er.java:68) at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyIn itializer.java:111) at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitiali zer.java:150) at com.model.Entity$$EnhancerByCGLIB$$b82499d4.toString(<generated>)The call to toString() or any of the getters() results in Hibernate attempting to fetch the record from database. And I haven't overloaded any methods. All calls for toString(),hashCode() and equals() went to the Object class.
As no record with id 999 exists the exception is thrown.
If load() does not result any data fetch then why use it ??
Consider the creation of an entity which also involves an association.Session session = sessionFactory.openSession();
Entity entity1 = new Entity();
Parent parent = (Parent) session.load(Parent.class, 9);
entity1.setParent(parent);
Here we are trying to create a new instance of entity. We need to create the association between entity and the parent. It is only the identifier of parent that is necessary for this operation. As no parent data is necessary for this, Hibernate is saved the firing of the select query. The proxy contains the minimum information necessary - the identifier - this is all that is needed to create the above association.In the next post we shall see what happens if we get and load the same object in one session ? Also how do associations behave when we get or load objects?
No comments:
Post a Comment