【问题标题】:LazyInitializationException when trying to access detached objects left around in Redis by RedisCacheManager尝试访问 RedisCacheManager 留在 Redis 中的分离对象时出现 LazyInitializationException
【发布时间】:2014-12-19 07:27:43
【问题描述】:

我使用 Spring 数据 Redis 以便使用 org.springframework.data.redis.cache.RedisCacheManager 在 Redis 中缓存序列化的 JPA 实体

方法如下:

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

不幸的是,在我的启动应用程序重新启动后,实体仍然缓存在 Redis 中,我收到了 org.hibernate.LazyInitializationException

这可能是由于in this post 所描述的原因,即通过休眠访问分离的对象 - 在我的情况下,序列化的对象留在缓存中。

有人可以建议解决此问题的策略吗?

  1. 我是否应该在销毁我的应用程序时清理/清空缓存,记住重新填充缓存的过程很昂贵,并且该应用程序将托管在云 (Heroku) 中,测功机/容器被销毁并重新创建(并因此重新启动)非常频繁。
  2. 或者有没有办法将缓存的实体重新附加到实体管理器?
  3. 有更好的解决方案吗?

【问题讨论】:

  • 我很困惑。为什么不使用 Hibernate 二级缓存支持?对这样的对象使用缓存抽象对我来说似乎是一个错误的想法。另一个问题是您的密钥,根本没有考虑 memberId,因此您基本上缓存了具有相同 ID 的所有内容。关于为什么应该使用方法名称作为键的一部分的更多想法:jira.spring.io/browse/…
  • 感谢您的意见 Stéphane。我想使用 Hibernate 二级缓存,但我的应用程序面向云(即 Heroku),它将存在于多个测功机/实例上......可以将 Redis 用作二级缓存吗?请忽略上面的缓存键。 :-)
  • 我还是不明白问题出在哪里。你见过github.com/debop/hibernate-redis 吗?我从未尝试过,但值得一试。

标签: hibernate jpa spring-data-jpa spring-cache spring-data-redis


【解决方案1】:

从未使用过 Redis,但如果您的缓存应该在应用程序重新启动时保持不变,您可能希望在缓存实体之前获取所有需要的关系。另一个问题可能是那些缓存的实体是分离的,如果您想在事务中再次使用它们,这可能是一个问题。当然,您可以通过调用 merge(entity) 重新附加它们,另一方面,这可能会导致用缓存的数据覆盖新数据时出现问题。

持久缓存要考虑的另一件事是类版本,因为如果您在重新部署之间更改类,如果缓存已经填充了先前类版本的实例,反序列化将失败。

【讨论】:

  • 您关于在重新部署之间更改类版本的观点很重要且相关:我没有考虑到这一点......谢谢。
  • 有人可以就处理此问题的最佳做法提出建议吗?
猜你喜欢
  • 2023-04-04
  • 1970-01-01
  • 2014-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多