Почему Grails / GORM / Hibernate ударил мои сеттеры по .save () и что с этим делать? - PullRequest
0 голосов
/ 20 января 2012

У меня есть DomainClass с двумя переменными, и пользователь может установить только одну или другую.Тот, который они не устанавливают, определяется некоторым кодом в установщике того, который они установили.Поэтому, если они устанавливают A, B устанавливает то, что я хочу, а если они устанавливают B, A устанавливает то, что я хочу.У меня проблема в том, что .save() GORM или Hibernate или что-то еще влияет на сеттеры.

Вот мой пример домена, добавленного в свежий проект 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 / PleaseExplainпросто "поиграть с моими сеттерами" до того, как мои вещи сохранятся?

Этот вопрос: Почему сеттеры в Grails вызывают дважды при сохранении? , кажется, также затрагивает проблему, но я 'Я все еще не знаю, что происходит и как решить мою проблему.

Ответы [ 3 ]

2 голосов
/ 20 января 2012

Это происходит потому, что Hibernate автоматически использует сеттеры при настройке свойств при загрузке.Вам нужен доступ на уровне поля к этим свойствам в спящем режиме.

Смотрите, как это реализовать.

Grails: доступ к полю с помощью GORM

1 голос
/ 20 января 2012

Другой способ сделать это - сохранить значение в одном значении, но вы используете временное свойство в качестве значения, с которым взаимодействует ваш код. Установщик для временного свойства содержит дополнительный код, а также устанавливает «реальное» значение, о котором знает 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 соответствуют имени файла без _.

0 голосов
/ 20 января 2012

Вот мое хакерское решение:

Заменить строку 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

...