为什么 Grails/GORM/Hibernate 在 .save() 上击中了我的 setter 以及该怎么办?
我有一个包含两个变量的 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 只是“玩弄我的设置器” “在它坚持我的东西之前?
这个问题: 为什么 Grails 中的 setter 在保存时被调用两次?< /a> 似乎也触及了这个问题,但我仍然想知道发生了什么以及如何解决我的问题。
I have a DomainClass with two variables and the user can only set one or the other. The one they don't set is determined by some code in the setter of the one they set. So if they set A, B gets set what I want, and if they set B, A gets set what I want. The problem I'm having is that on .save()
GORM or Hibernate or something is hitting the setters as well.
Here is my example domain added to a fresh grails 2.0 project called l2getset:
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 = {
}
}
And the bootstrap:
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 = {
}
}
Prints:
| 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
How do I differentiate between when I "legitimately" set one of these and when GORM/Hibernate/PleaseExplain is just "playing around with my setters" before it persists my stuff?
This question: Why are setters in Grails called twice on save? appears to also touch on the issue, but I'm still left wondering what is going on and how to tackle my problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
另一种方法是将值保留在一个值中,但使用瞬态属性作为代码交互的值。瞬态属性的设置器中有额外的代码,它还设置 hibernate 知道的“真实”值。
例如:
prints:
如果需要,您可以扰乱域类的映射,告诉它
_thisIsA
和_thisIsB
字段映射到不带 < 的文件名代码>_。Another way to do this is to have the value be persisted in one value, but you use a transient property as the value that your code interacts with. The setter for the transient property has your extra code in it, and it also sets the "real" value that hibernate is aware of.
Ex:
prints:
If you need to, you can mess with the mapping of the domain class to tell it that the
_thisIsA
and_thisIsB
fields map to a file name without the_
.这是我的黑客解决方案:
将
void setThisIsA
中的行this.thisIsB = 'user set A'
替换为以下堆栈跟踪检查:反之亦然 <代码>无效setThisIsB
Here is my hack solution:
Replace the line
this.thisIsB = 'user set A'
invoid setThisIsA
with the following check of the stack trace:And do vice versa for
void setThisIsB
发生这种情况是因为 hibernate 在加载时设置属性时自动使用 setter。您想要的是在 hibernate 中对这些属性进行字段级访问。
请参阅此了解如何实施它。
Grails:使用 GORM 进行现场访问
It's happening because hibernate automatically uses setters when setting properties when you load. What you want is field-level access to these properties in hibernate.
See this for how to implement it.
Grails: field access with GORM