I am working on an application which relies on caching using mostly reads and some updates.
The technology stack I am using is Spring + Hibernate + Ehcache. I need to serve the requests using the cache and not hit the database at all. The approach I am following is to cache all of the data at the application start up using queries such as getSession().createCriteria(<Entity>.class).list()
and then ask Hibernate for entities using a session.get()
call so that it uses the second level cache to resolve.
One challenge I see is my entity classes have a lot of collection and association attributes (Many-to-Many with extra columns, One-to-Many, One-to-One).
I have two approaches for such a cache:
Keep all relationships as EAGER fetch. The cache will be filled with the data with a big query containing left outer joins on startup. I am concerned that loading data eagerly may cause unnecessary long running queries returning multiple rows.
Keep relationships as LAZY and iterate over all the rows and call .getSetOf<Entity>
to load related entities. I am concerned that I will be virtually iterating all of the data at startup and I'm not sure if whether this is a good practice.
Since the associations in Hibernate are associated using composition and foreign keys and not stored as individual IDs, loading of such associations/collections seems to be overhead.
I would have preferred having table data in different cache regions with their foreign key relationships as just IDs (not compositions/collections). I would have cached all such entities in different regions and would have combined the results at runtime by iterating over those regions.
Can anyone suggest what approach should I follow? If there is any alternate approach, do suggest.
I am working on a project having technology stack spring+hibernate+hazelcast . I am using hibernate 2nd level cache also. We also load data into cache on server startup. According to me you should not do all collections of an entity eager as it makes the object very heavy.We are using mixed approach.Some of our collections are eager and some are lazy depending upon the requirement. If your collection has very large data then make it lazy otherwise make it eager. One more thing we are doing,we are using LEFT JOIN FETCH
in queries which loads the collections also if collections are defined lazy.For eg:-
SELECT DISTINCT userInfo FROM UserInfo userInfo
LEFT JOIN FETCH userInfo.userRoles
LEFT JOIN FETCH userInfo.regions
LEFT JOIN FETCH userInfo.countries
In my entity UserInfo , i have made region Eager (because regions are less in number) and countries Lazy (because countries are more in number).Now my this query still returns userInfo object fully loaded with countries and region.And due to Left Join Fetch no multiple queries get executed.
I hope this can help you.
It's not clear from your description if your application controls access to the database.
Just to make it clear, I'm not anti OO or Hibernate or Ehcache. I'm just wondering if they're a good fit for your (limited) description.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.