我有一个包含两个变量的DomainClass,用户只能设置一个或另一个。他们没有设置的那个是由他们设置的那个中的一些代码决定的。因此,如果他们设置了A,B就会设置我想要的东西,如果他们设置了B,A就会得到我想要的东西。我遇到的问题是在.save()
GORM或Hibernate上,或者某些东西也在击中设置者。
这是我的示例域添加到名为l2getset的新grails 2.0项目:
package l2getset
class ExampleDomain {
String thisIsA
String thisIsB
void setThisIsA(String thisIsA){
println "Hitting A Setter"
this.thisIsA = thisIsA
this.thisIsB = 'user set A'
}
void setThisIsB(String thisIsB){
println "Hitting B Setter"
this.thisIsB = thisIsB
this.thisIsA = 'user set B'
}
static constraints = {
}
}
引导程序:
import l2getset.*
class BootStrap {
def init = { servletContext ->
def someExample = new ExampleDomain()
someExample.thisIsA = "Some String"
println "Some Example is: ${someExample.thisIsA} / ${someExample.thisIsB}"
someExample.save()
println "Some Example is: ${someExample.thisIsA} / ${someExample.thisIsB}"
}
def destroy = {
}
}
打印:
| Running Grails application
Hitting A Setter
Some Example is: Some String / user set A
Hitting A Setter
Hitting B Setter
Some Example is: user set B / user set A
| Server running. Browse to http://localhost:8080/l2getset
我如何区分何时“合法地”设置其中一个以及何时GORM / Hibernate / PleaseExplain只是“与我的二传手一起玩”才能保留我的东西?
这个问题:Why are setters in Grails called twice on save?似乎也触及了这个问题,但我仍然想知道发生了什么以及如何解决我的问题。
答案 0 :(得分:2)
这种情况正在发生,因为在加载时设置属性时,hibernate会自动使用setter。你想要的是在hibernate中对这些属性的字段级访问。
请参阅此内容以了解如何实施它。
答案 1 :(得分:1)
另一种方法是将值保存在一个值中,但是使用transient属性作为代码与之交互的值。瞬态属性的setter中包含额外的代码,它还设置了hibernate知道的“真实”值。
前:
package l2getset
class ExampleDomain {
String _thisIsA
String _thisIsB
static transients = ["thisIsA", "thisIsB"]
String getThisIsA() { _thisIsA }
void setThisIsA(String thisIsA){
println "Hitting A Setter"
this._thisIsA = thisIsA
this._thisIsB = 'user set A'
}
String getThisIsB() { _thisIsB }
void setThisIsB(String thisIsB){
println "Hitting B Setter"
this._thisIsB = thisIsB
this._thisIsA = 'user set B'
}
}
打印:
Running Grails application..
Hitting A Setter
Some Example is: Some String / user set A
Some Example is: Some String / user set A
Server running. Browse to http://localhost:8080/transient-setter
如果需要,您可以搞乱域类的映射,告诉它_thisIsA
和_thisIsB
字段映射到没有_
的文件名。
答案 2 :(得分:0)
这是我的黑客解决方案:
使用以下对堆栈跟踪的检查替换this.thisIsB = 'user set A'
中的行void setThisIsA
:
StringWriter sw = new StringWriter();
new Throwable("").printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();
if(!stackTrace.find('DefaultSaveOrUpdateEventListener')){
this.b = 'user set A'
}
对void setThisIsB