grails - 为什么 Grails 命令对象默认提交对域对象的更改?

标签 grails grails-orm

如果我在我的 Grails 命令对象中使用 GORM 域对象,即使我没有调用 save() 方法,命令对象也会自动提交对域对象的更改。

我想绑定(bind)到命令对象中的 GORM 对象,但不保存或提交对数据库的更改。如果我的 Controller 或我的服务抛出异常,我想要事务回滚。

我可以使用以下注释强制执行我想要的行为,但这感觉就像我正在努力地做这件事。

Controller Class = @Transactional(readOnly = true)
Controller action method = @Transactional
Command Object Class = @Transactional(readOnly = true)
Service Class = @Transactional

我做错了什么吗,除非我添加所有这些注释,否则 Grails 域对象是否应该由命令对象自动提交?

最佳答案

这不是特定于命令对象,它是 Controller Action 的一般特征。默认情况下,open-session-in-view 模式处于事件状态,其中在操作运行之前创建 Hibernate Session 并绑定(bind)到线程本地,并在操作完成后刷新并关闭它。从数据库中检索到的任何持久实例(无论是由于查询而显式地检索,还是在数据绑定(bind)期间隐式地检索)都将保持连接到打开的 session ,并在 session 刷新时进行脏检查。任何修改后的实例都将与其他排队的操作一起刷新其更改,无论是否带有 save()称呼。

使整个方法(或类)具有事务性和只读性可能是矫枉过正。更直接的方法是将实例检索为只读,例如使用 read()而不是 get() , 调用readOnly执行条件查询等时的方法,或通过调用 discard() 来“分离”修改的实例每个方法。另一种选择是在操作结束时清除 session ,这样就不会自动刷新,例如

AnyDomainClass.withSession { it.clear() }

请注意,在“只读”模式下检索的实例可以保留其更改,但 Hibernate 不会自动为这些实例执行任何操作,它只会在您显式调用 save() 时发生。 .

关于grails - 为什么 Grails 命令对象默认提交对域对象的更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37264724/

相关文章:

java - 循环创建动态 SQL 字符串

grails - Spring Boot、GORM 和单元测试

maven - Grails Maven 解析器不适用于 2.3.8

grails - 域约束不起作用

java - XmlSlurper获取节点值说明

linux - 从 linux 以 Debug模式运行 Grails 2.3.1

Grails 3.1.1 - 当模型类扩展另一个 groovy 类时,脏检查不起作用

performance - Grails hibernate session 批量

sql-server - Grails dbCreate ='validate' 无法识别现有表

hibernate - 在 grails 事务上捕获 RuntimeExceptions