Hibernate has two type of fetching by default. With the help of these we can make sense for most association in the majority of application. which is below:
1. uses lazy select fetching for collections
2. lazy proxy fetching for single-valued associations.
When we set hibernate.default_batch_fetch_size, doing this Hibernate will use the batch fetch optimization for lazy fetching. This optimization can also be enabled at a more granular level.We should aware that access to a lazy association outside of the context of an open Hibernate session will result in an exception.
s = sessions.openSession();
Transaction tx = s.beginTransaction();
User u = (User) s.createQuery("from User u where u.name=:userName")
Map permissions = u.getPermissions();
Integer accessLevel = (Integer) permissions.get("accounts"); // Error!
Till then the permissions collection was not initialized when the Session was closed, the collection will not be able to load its state. Hibernate does not support lazy initialization for detached objects. This can be fixed by moving the code that reads from the collection to just before the transaction is committed.
Alternatively, we can use a non-lazy collection or association, by specifying lazy="false" for the association mapping. It is intended that lazy initialization be used for almost all collections and associations. If define too many non-lazy associations in your object model, Hibernate will fetch the entire database into memory in every transaction.
On the other hand, you can use join fetching, which is non-lazy by nature, instead of select fetching in a particular transaction. We will now explain how to customize the fetching strategy. In Hibernate3, the mechanisms for choosing a fetch strategy are identical for single-valued associations and collections.