I am storing the hibernate entities in ehcache. When a call is made to facade layer to retrieve an entity, my interceptor will invoke that method and caches it. Next time when the same method is called, the entity will be returned from the cache. This all works fine.
My entity has some properties(objects or associated entities) which are defined as FetchType.Lazy. Its something like this ,
@JoinColumn(name = "inventory_item_oid", referencedColumnName = "inventory_item_oid")
@ManyToOne(fetch = FetchType.LAZY)
private InventoryItem inventoryItem;
Hence, not all the properties are loaded. When the Inventory Item is needed its called. This call is throwing the LazyInitialization Exception.
As my cached values live for one day, it can be called any number of times, before it gets expired.
One of these calls throwing the above exception.
I came to find that using long hibernate sessions, I can solve this problem. But it doesnt work because mine is request/response based application.
There is one more way where I need to check if InventoryItem is null or not before accessing its properties, if its null, then I need to fetch that value separately and attach it to the parent. This seems to be Good...but needs lot of work as I have many entities.
I would like to know if there is any other way I can fetch those objects defined as lazy.
You shouldn't cache entities in EHCache yourself. Instead, you should configure Hibernate to use a second-level cache, and use EHCache as its implementation.
The end result will be the same: your entities will be cached and you'll save roundtrips to the database. But by using the second-level cache, everything will be transparent: you'll load entities from the session, and Hibernate will automatically store them in the cache. And if you reload them from the session, Hibernate will get them from the cache. And if you update the entity, it will be evicted from the cache to make sure a fresh copy is reloaded next time.
Another huge difference with your hand-made solution is that Hibernate will return you attached entities. So if you just call cachedEntity.getNonCachedEntity(), Hibernate will lazy-load the non cached entity exactly as if you had no cache at all.
Whether the entity comes from the database or from the second-level cache doesn't change anything: if an attribute is lazy-loaded, and if this attribute is accessed once the session is closed, then the lazy attribute must be initialized before the session is closed.
Call Hibernate.initialize(foo.getInventotyItem()) to initialize it.
More info in the Hibernate documentation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With