为什么Grails/GORM/Hibernate在.save()上碰到了我的setters,该怎么办?

为什么Grails/GORM/Hibernate在.save()上碰到了我的setters,该怎么办?,hibernate,grails,save,gorm,setter,Hibernate,Grails,Save,Gorm,Setter,我有一个带有两个变量的DomainClass,用户只能设置其中一个变量。他们没有设置的是由他们设置的setter中的一些代码决定的。如果他们设置了A,B得到了我想要的,如果他们设置了B,A得到了我想要的。我遇到的问题是,在.save()GORM或Hibernate上,或者有什么东西也在影响setters 下面是我添加到新的grails 2.0项目l2getset中的示例域: package l2getset class ExampleDomain { String thisIsA St

我有一个带有两个变量的DomainClass,用户只能设置其中一个变量。他们没有设置的是由他们设置的setter中的一些代码决定的。如果他们设置了A,B得到了我想要的,如果他们设置了B,A得到了我想要的。我遇到的问题是,在
.save()
GORM或Hibernate上,或者有什么东西也在影响setters

下面是我添加到新的grails 2.0项目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 = {
  }
}
以及引导程序:

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/PleaseeExplain只是在“摆弄我的设置者”之前,我如何区分它们


这个问题:似乎也触及到了这个问题,但我仍然在想到底发生了什么以及如何解决我的问题。

这是因为hibernate在加载时设置属性时会自动使用setter。您需要的是在hibernate中对这些属性的字段级访问

有关如何实现它,请参见此


之所以发生这种情况,是因为hibernate在您加载时设置属性时会自动使用setter。您需要的是在hibernate中对这些属性的字段级访问

有关如何实现它,请参见此


这是我的黑客解决方案:

用以下堆栈跟踪检查替换
void setThisIsA
中的行
this.thisIsB='user set A'

StringWriter sw = new StringWriter();
new Throwable("").printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();
if(!stackTrace.find('DefaultSaveOrUpdateEventListener')){
  this.b = 'user set A'
}

对于
无效设置thisisb

则反之亦然。以下是我的黑客解决方案:

用以下堆栈跟踪检查替换
void setThisIsA
中的行
this.thisIsB='user set A'

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

反之亦然。另一种方法是将值持久化到一个值中,但您使用瞬态属性作为代码与之交互的值。transient属性的setter中有您的额外代码,它还设置hibernate知道的“real”值

例:

印刷品:

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

如果需要,您可以处理域类的映射,告诉它
\u thisIsA
\u thisIsB
字段映射到一个文件名,而不使用
\u

另一种方法是将该值持久化到一个值中,但您使用瞬态属性作为代码与之交互的值。transient属性的setter中有您的额外代码,它还设置hibernate知道的“real”值

例:

印刷品:

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

如果需要,可以处理域类的映射,告诉它
\u thisIsA
\u thisIsB
字段映射到一个文件名,而没有
\u

,这对于我正在寻找的功能来说似乎很重要。是否有某种groovy hack来检查它是如何被调用的,并确定它是否来自hibernate.save()?这其实并不难。请看我对另一个问题的评论。对于我所寻找的功能来说,这似乎太多了。是否有某种groovy hack来检查它是如何被调用的,并确定它是否来自hibernate.save()?这其实并不难。请参阅我对另一个问题的评论。增加了大约12毫秒的开销,因此我将以正确的方式进行操作。增加了大约12毫秒的开销,因此我将以正确的方式进行操作。这是一个好主意,但它针对我的实际问题进行了分解。谢谢你的建议-我可能会在那条路上使用它。这是一个好主意,但它会因为我的实际问题而崩溃。谢谢你的建议-我可能会在那条路上用这个。