What is proxy in the context of load() method of Hibernate?

Proxy objects are empty instances which are used in Lazy Loading for initialising the object fields when they are demanded using getter method. Until then the object is empty containing only the main ID.


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

This is similar to lazy-loading of associations, but might be seen as more of a "lazy-create".

A proxy is a subclass implemented at runtime. Hibernate creates a proxy (a subclass of the class being fetched) instead of querying the database directly, and this proxy will load the "real" object from the database whenever one of its methods is called.

The second highlighted text explains that if you call load() on multiple instances, you can fetch them as a batch, and in that way reduce roundtrips to the database.

This is also the difference between load() and get(), load sort of lazy-loads the object, while get fetches the object from the database right away