我正在使用grails缓存插件来缓存一组gorm对象。此方法在服务中
@Cacheable('allBooks')
List<Book> getAllFictionBooks() {
log.info("Looking up all books and adding them to a cache")
Book.findAllByIsFiction(true)
}
然而,在服务器重启时,我收到此错误,并且经常需要第二次重启我的服务器
failed to lazily initialize a collection of role: com.Book.applyTo, no session or session was closed
我添加了
grails.cache.clearAtStartup = true
到Config.groovy,但似乎没有帮助。我可能做了一些愚蠢的事。任何帮助深表感谢。
我正在使用Grails 2.2.1。插件:缓存:1.1.1
答案 0 :(得分:1)
您不希望使用缓存插件缓存GORM查询结果 - Hibernate已经通过查询缓存支持此功能。并且它更加强大,特别是失效。例如,如果您的查询返回4本书,但在将来的某个时刻添加了新的小说书,则需要手动删除此结果。但是Hibernate已经这样做了 - 任何新的,删除的,甚至修改过的书都会导致所有带有书籍的缓存结果被删除。
但是你看到的问题是,显然你有一个懒惰的applyTo
集合。一旦查询运行并将值存储在Spring管理的缓存中,然后Web请求结束,Hibernate会话将关闭,实例将断开连接。稍后访问任何未初始化的延迟属性将触发您看到的异常,除非您将实例重新附加到当前会话,例如与merge()
。但是如果您使用二级缓存,Hibernate会为您做到这一点。
二级缓存也很容易可群集。添加第二个Web服务器后,您需要确保没有2个独立的缓存,而是2个相互更新以保持同步的缓存。这显然可以通过Spring缓存来实现,但是使用Hibernate / GORM更简单。