3. Proxies
An object proxy is just a way to avoid retrieving an object until you need it. Hibernate 2 does not proxy objects by default. However, experience has shown that using object proxies is preferred, so this is the default in Hibernate 3.
Object proxies can be defined in one of two ways. First, you can add a proxy attribute to the class element. You can either specify a different class or use the persistent class as the proxy. For example:
<class name="Location"
proxy="com.manning.hq.ch03.Location"...>...
</class>
The second method is to use the lazy attribute. Setting lazy="true"is a shorthand way of defining the persistent class as the proxy. Let's assume the Location class is defined as lazy:
<class name="Location"lazy="true"...>...</class>
The lazy attribute is true by default in Hibernate 3. An easy way to disable all proxies, including lazy collections, is to set the default-lazy attribute to true in the hibernate-mapping element for a given mapping file. Let's look at an example of using a proxied Location instance:
Session session =factory.openSession();
Event ev =(Event)session.load(Event.class,myEventId);
Location loc =ev.getLocation();
String name =loc.getName();
session.close();
The returned Location instance is a proxy. Hibernate populates the Location instance when getName()is called.
You'll be dealing with a proxy of Location generated by CGLIB until you call an instance method. (CGLIB is a code generation library used by Hibernate. You can find out more about it at http://cglib.sourceforge.net/.) What happens when you retrieve the Event instance from the database? All the properties for the Event are retrieved, along with the ID of the associated Location instance. The generated SQL looks something like this:
select event0_.id as id0_,event0_.name as
name0_,event0_.location_id as location_id0_from events event0_where event0_.id=?
When you call loc.getName(), the following generated SQL is executed:
select location0_.id as id0_as id0_,location0_.name as
name0_from locations location0_where location0_.id=?
If you've guessed that you can call loc.getId()without invoking a call to the database, you're correct. The proxied object already contains the ID value, so it can be safely accessed without retrieving the full object from the database.
