Grails域对象不被保留

时间:2017-06-23 14:43:16

标签: hibernate grails gorm

Grails 3.2.10,Gorm 6.1.4,Hibernate 5.2.9

我有一个grails域对象和一个执行基本crud操作的相应控制器(它不是脚手架)。将Command对象提交给控制器的更新方法时,控制器按预期执行(所有日志消息都按照应用的方式打印)并且不会抛出任何错误。显示重定向页面就像您期望显示的Flash消息一样(即使使用更新的数据)。但是,数据库值实际上不会更新。我可以创建对象,它只会用于更新。

2 个答案:

答案 0 :(得分:1)

在经历了很多挫折之后,似乎最新的Gorm或Hibernate正在监视域对象上的setXXX方法,如果这些方法没有被调用,那么hibernate将不会看到对象被修改并且不会更新任何变化。调高日志级别帮助我看到hibernate没有看到对象被修改,因此无视它。

我的问题集中在调用setData(CommandObject)的域对象中有this.xxx = CommandObject.xxx;个方法,因此通过生成的setter并导致hibernate认为对象没有被修改。

直接从控制器调用setter是解决此问题的方法。

示例(不起作用):

class Person {
  String name
  //...typical constraints, methods, etc...
  void setData(PersonCommand c){
    this.name = c.name;
  }
}

class PersonController {
  //...typical list, show, create methods...
  def update(PersonCommand pc){
     //... validation ...
     Person p = Person.get(pc.personId);
     p.setData(pc);
     p.save(failOnError: true);
     flash.message = "Successfully saved person ${p.name}"
     redirect(action: 'show', id: p.id)
  }
}

固定示例(可行):

class Person {
  String name
  //...typical constraints, methods, etc...
}

class PersonController {
  //...typical list, show, create methods...
  def update(PersonCommand pc){
     //... validation ...
     Person p = Person.get(pc.personId);
     p.name = pc.name;
     //... set other fields ...
     p.save(failOnError: true);
     flash.message = "Successfully saved person ${p.name}"
     redirect(action: 'show', id: p.id)
  }
}

答案 1 :(得分:0)

这是一个众所周知的域类问题。你必须在其他域类的方法中明确地调用setter或getter:

class Person {
  String name
  void setData(PersonCommand c){
    setName c.name
  }
}

此外,我将setData()重命名为applyData(),以避免与POGO方法发生冲突