我遇到了一些Grails
代码,如下所示:
Book.saveAll(bookList)
其中bookList
是List
个Book
个域实例。虽然在Book
时这似乎工作正常(保存所有run-app
实例),但功能测试失败并出现以下错误:
Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
然后我想看一些关于saveAll
的文档,我似乎无法找到任何文档。有文件吗?该方法是否应该使用?
答案 0 :(得分:4)
基本上,saveAll不会刷新。如果您希望立即在数据库中进行更改,则在使用saveAll之后,您可以获取当前会话并刷新它。 Hibernate的工作原理是:当你调用flush时,它会刷新Hibernate会话,立即将会话中的所有数据持久化到数据库。如果不使用(flush:true),则数据仅记录在Hibernate会话中,并且仅在刷新Hibernate会话时才会持久存储在数据库中。 Hibernate会自动确定刷新会话的时间,以优化性能。 有不同的冲洗方式,您可以保存所有数据并最后冲洗。
def hibSession = sessionFactory.getCurrentSession()
hibSession.flush()
我们遇到了同样的问题。测试哪种方法更快。测试完成了300项。
list.each { Book.save(flush:true,failOnError:true) }
list.each {Book.save()};
def hibSession = sessionFactory.getCurrentSession();
hibSession.flush()
Book.saveAll(列表);
def hibSession = sessionFactory.getCurrentSession();
hibSession.flush()
答案 1 :(得分:1)
我不确定为什么没有记录,但文档中存在相当多的空白:)虽然实现非常基本,但它只是遍历列表并在每个上面调用save
。所以你可以把它转换成你自己的循环,它应该适用于两种情况,例如。
for (book in bookList) {
book.save()
}
这样做的好处是,您可以检查循环中每个错误,并且更明显的是保存了多个内容,并且这应该在事务中完成。