The Hibernate documentation for the load()
method says:
Be aware that load() will throw an unrecoverable exception if there is no matching database row. If the class is mapped with a proxy, load() just returns an uninitialized proxy and does not actually hit the database until you invoke a method of the proxy. This is useful if you wish to create an association to an object without actually loading it from the database. It also allows multiple instances to be loaded as a batch if batch-size is defined for the class mapping.
Please help me to understand this by explaining the meaning of the parts highlighted above in bold.
By definition, a proxy is “a function authorized to act as the deputy or substitute for another”. This applies to Hibernate when we call Session. load() to create what is called an uninitialized proxy of our desired entity class. Simply put, Hibernate subclasses our entity class, using the CGLib library.
In hibernate, get() and load() are two methods which is used to fetch data for the given identifier. They both belong to Hibernate session class. Get() method return null, If no row is available in the session cache or the database for the given identifier whereas load() method throws object not found exception.
Explanation: load() method returns proxy object. load() method should be used if it is sure that instance exists.
Proxy is a structural design pattern that provides an object that acts as a substitute for a real service object used by a client. A proxy receives client requests, does some work (access control, caching, etc.) and then passes the request to a service object.
Proxies are classes generated dynamically by Hibernate to help with lazy loading. For instance, if you have a Cat
class, Hibernate will generate a proxy class that extends Cat
.
If you get an uninitialized instance of this proxy, essentially all its fields will be null except the ID because Hibernate has not yet hit the database. Now the first time you will call a method on this proxy, it will realize that it is not initialized and it will query the database to load it's attributes. This is possible because the dynamically generated class overrides the base class's methods and adds this initialized/uninitialized check.
Now assume that your Cat
class is not a proxy and that it has a father
association, when you load a Cat object, Hibernate will need to load all it's attributes. So if you load a Cat
object, Hibernate will also need to load its father and the father's father and so on. Using proxies enable Hibernate to only load the required instances.
Cat cat1 = (Cat) session.load(1); Cat cat2 = (Cat) session.load(2); Cat cat3 = (Cat) session.load(3); cat1.meow(); // this will cause Hibernate to run a query to load cat1's data cat2.meow(); // this will cause Hibernate to run a query to load cat2's data // After this cat3 is still an uninitiated proxy because it has not been used
batch-size
is another feature of Hibernate that, in most instances, help dealing with lazy loading. Basically the idea is that Hibernate keeps track of the uninitialized proxies and when one of the needs to be initialized, a single query will be executed to load up to batch-size
proxies (instead of just one proxy/query)
Cat cat1 = (Cat) session.load(1); Cat cat2 = (Cat) session.load(2); cat1.meow(); // if batch-size >= 2, cat1 and cat2 will be loaded in a single query cat2.meow(); // no query will be executed here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With