It’s painfully obvious how to lazily load collections in Hibernate. Simply set lazy=”true” and you’re ready to go. Doing the same for associated objects can be a bit more intimidating. The use of the term “proxy”, and no sign of the familiar lazy loading terminology can be a bit intimidating, but it really is just as trivial.
It’s not as intuitive because it’s accomplished indirectly. You actually have to change the related object rather than changing the relationship. Suppose we have a Cat object (the preferred object of Hibernate documentation), and each Cat has an Owner class associated with it via a many-to-one relationship. To ensure that the Owner is lazily loaded, we simply change the definition of the mapping of the Owner class, adding proxy=”net.sf.hibernate.Owner”. Now, any class that has a 1-1 or N-1 relationship to an Owner will default to lazily-loading the Owner object.
In practice, the proxy functionality allows so much more than this, but for a quick solution, it works like a charm. Especially interesting is how Hibernate uses CGLib to create the proxy interface for the class on-the-fly. It appears to create a wrapper class around your object that extends each method to first check for the initialization of the object, and then, if/when initialized, returns the expected result.
One gotcha here is that specifying a proxy makes lazy loading the default behavior for all relationships. To override this, I believe an “outer join fetch” is needed in an HQL query. Still, this sort of strategy is used when tuning an application, so outer join fetches and such are a necessary evil(?) anyhow.