Grails Domain Class中Transient方法修改属性未标记为Dirty的问题
解决Grails Domain类中Transient方法修改属性后未标记为Dirty的问题
这个问题我之前也碰到过,本质是Grails ORM的代理机制在背后影响,我来给你拆解原因和解决方案:
问题根源
Grails的Domain类在运行时会被动态生成代理类,它会给每个属性的setter方法做增强——当你通过setter修改属性时,代理类会自动标记对象为dirty状态。但你在update方法里直接给字段major赋值(major = newVal),是绕过了这个增强的setter方法,所以ORM无法感知到属性变化,自然不会标记对象为dirty。
而你在方法外部直接修改属性时,比如major.major = "NEW VALUE",实际上调用的是代理类生成的增强setter方法,所以能正常触发脏状态标记。
解决方案
这里有两种简单有效的解决办法:
方法1:调用属性的setter方法
在update方法里,不要直接给字段赋值,而是调用Grails生成的setter方法(Groovy的属性语法本质也是调用setter):
class Major { String code String major static transients = ['update'] def update(String newVal) { // 方式1:直接调用setter方法 this.setMajor(newVal) // 方式2:用Groovy属性语法,本质和调用setter一致 // this.major = newVal } }
方法2:手动标记对象为Dirty
如果你确实需要直接操作字段,可以在修改后手动调用markDirty()方法,强制标记对象为dirty:
class Major { String code String major static transients = ['update'] def update(String newVal) { major = newVal // 手动触发脏状态标记 markDirty() } }
两种方法都能让你的major.dirty返回true,之后调用save()就能正常保存修改了。
内容的提问来源于stack exchange,提问作者Raymond Holguin
相关产品推荐
相关产品推荐

