I am trying to give second level cache and query cache a try for my project. here is the versio information:
1. Hibernate: 3.3.2 2. EHCache: 1.6.0
However, although query cache seems to be working. It always return result with lazy collections, even if my original query eagerly fetch the collections. For example:
In Service class // open session criteria = session.createCriteria(Podcast.class); criteria.setFirstResult(offset); org.hibernate.Criteria criteria = session.createCriteria(Podcast.class); criteria.setFetchMode("podcastCategoryMappings", FetchMode.JOIN); criteria.add(Restrictions.in("id", podIds)); criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); criteria.addOrder(Order.asc("title")); criteria.setCacheable(true); // turn on cache podcasts = criteria.list(); // close session
In client class, I expect getting a podcast class, with podcastCategoryMappings collection fetched.
@Test public void testGetAllPodcasts() { // first time, it goes through database, and put into cache the query result (id=1), entity (podcast), collections(podcastCategoryMapppings) List<Podcast> podcasts = _service.getPodcasts(0, 1);
for (Podcast pod: podcasts) { Set<PodcastCategoryMapping> mappings = pod.getPodcastCategoryMappings(); for (PodcastCategoryMapping mapping: mappings) { System.out.println("pod title/id: " + pod.getTitle() + "/" + pod.getId() + " category id: " + mapping.getCategoryId()); } // second time, the results come from cache. I shall expect cache hit for query result, entity(podcast), and collections. // However, i only see cache hit for query result and entity, not the collections. podcasts = _service.getPodcasts(0, 1);
// It will fail with LazyInitializationException since collection is not fully initialized when result returned from cache for (Podcast pod: podcasts) { System.out.println("pod id: " + pod.getId()); Set<PodcastCategoryMapping> mappings = pod.getPodcastCategoryMappings(); for (PodcastCategoryMapping mapping: mappings) { System.out.println("pod title/id: " + pod.getTitle() + "/" + pod.getId() + " category id: " + mapping.getCategoryId()); } } }
I turned on the debug message for hibernate cache related classes, so that I know what is wrong with cache. log4j.logger.org.hibernate.cache.ReadWriteCache=TRACE log4j.logger.org.hibernate.cache.UpdateTimestampsCache=TRACE log4j.logger.org.hibernate.cache.StandardQueryCache=TRACE
Can someone from hibernate team take a look at this and confirm if this is a bug? I am very close to place this into a project. If this is not working, I guess, I have to manage cache myself, rather than using hibernate to manage the cache. The bottom line is that cache should not return inconsistent result like this.
Thanks.
|