Assume we use the load() method, lets pinpoint when a proxy will be returned, and when an ObjectNotFoundException will be thrown.
Scenario #1: Item entity is configured such that hibernate is allowed to proxy it.
In this case, if the Item instance exists in the session cache, it will be returned, otherwise a proxy will be returned. If an actual instance was returned in the first place, we will be fine when we access Item’s properties. If a proxy was returned to begin with, then an ObjectNotFoundException will be thrown if we access the properties of the Item proxy, and the actual Item doesn’t exist in the database.
Note: You may access the identifier property without raising the exception.
Scenario #2: Item entity is configured such that hibernate is not allowed to proxy it.
In this case, hibernate will try to return the actual instance always. So, if an instance exists in the session cache, it will be returned. If not, since hibernate is not allowed to proxy it, it will make a trip to the database to find the instance. If present, the instance will be added to the session cache and returned. Otherwise, an ObjectNotFoundException will be thrown.
Hope this clarifies.