0

I use Spring data Redis in order to cache serialized JPA entities in Redis using org.springframework.data.redis.cache.RedisCacheManager

Here is the method:

@Override
@Cacheable(value = MapCacheConfiguration.DATABASE_CACHE_NAME, key = "#root.method.name")
public Curriculum findCurriculumByMemberId(Long memberId) {
    return curriculumRepository.findCurriculumByMemberId(memberId);
}

Unfortunately, upon restart of my boot application, the entities are still cached in Redis and I get a org.hibernate.LazyInitializationException

This might be for the reason described in this post i.e. access to a detached object by hibernate - in my case the serialized object left around in the cache.

Can someone please advise a strategy for dealing with this problem?

  1. Should I clean/empty the cache upon destroy of my app bearing in mind the process of repopulating the cache is expensive and the app is going to be hosted in the cloud (Heroku) where the dynos/containers are destroyed and recreated (and therefore restarted) quite frequently.
  2. Or is there a way to reattach to the cached entities to the entity manager?
  3. Is there a better solution?
Community
  • 1
  • 1
balteo
  • 23,602
  • 63
  • 219
  • 412
  • I am confused. Why aren't you using Hibernate second level cache support? Using the cache abstraction for such object seems like a wrong idea to me. The other problem is your key, the memberId is not taken into account at all so you basically cache everything with the same id. More thoughts on why you should **not** use the method name as part of the key: https://jira.spring.io/browse/SPR-11736?focusedCommentId=102517&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-102517 – Stephane Nicoll Oct 25 '14 at 08:30
  • Thanks for your input Stéphane. I would like to use Hibernate Second level caching but my app is targeted for the cloud (i.e. Heroku) where it will live on several dynos/instances... It is possible to use Redis as a 2nd level cache? Please ignore the cache key above. :-) – balteo Oct 25 '14 at 09:44
  • I still don't see what the problem is. Have you seen https://github.com/debop/hibernate-redis ? I never tried it but it's worth trying. – Stephane Nicoll Oct 25 '14 at 11:52

1 Answers1

1

Never used Redis, but if your cache is supposed to be persistent across application restarts you might want to fetch all needed relations before caching the entity. One other concern could be that those cached entities are detached, which can be a problem if you want to use them again in transactions. Of course, you might reattach them by calling merge(entity), which on the other hand could cause problems with overriding new data with cached ones.

Another thing to consider with persistent cache is class versions, because if you change your classes between redeploys, deserialization will fail if cache is already populated with instances of previous class version.

Predrag Maric
  • 23,938
  • 5
  • 52
  • 68
  • Your point about classes versions changing between redeploys is important and relevant: I had not taken that into account... Thanks. – balteo Oct 23 '14 at 15:57
  • 1
    Can someone please advise on a best practice to deal with this issue? – balteo Oct 23 '14 at 21:04