未保存域方法中的Grails 3.3.10值集

未保存域方法中的Grails 3.3.10值集,grails,grails-3.3,Grails,Grails 3.3,我有一个具有resetPasswordToken属性的用户类,当用户尝试重置密码时,该属性是一个UUID集 在Grails 2.5.6上,我有这样的东西可以正常工作: class UserController { def forgotPassword(String email) { ... def user = User.findByEmail(email) user.setPasswordToken() user.save(flu

我有一个具有resetPasswordToken属性的用户类,当用户尝试重置密码时,该属性是一个UUID集

在Grails 2.5.6上,我有这样的东西可以正常工作:

class UserController {


   def forgotPassword(String email)
   {
      ...
      def user = User.findByEmail(email)
      user.setPasswordToken()
      user.save(flush: true()
      ...
   }
}

class User {

   ...
   String resetPasswordToken

   static transients = ['passwordToken']

   def setPasswordToken()
   {
      ...
      this.resetPasswordToken = (java.util.UUID.randomUUID() as String)
   }
}
现在我将其迁移到GRails 3.3.10,在调用forgotPassword操作后,数据库上的resetPasswordToken为NULL。如果在调用user.setPasswordToken()后执行println,我可以看到resetPasswordToken被设置为UUID,但不在DB中。还检查了保存时的错误,没有错误

奇怪的是,如果我在控制器中执行了user.resetPasswordToken=“xxxx”,则值会正确地保存到数据库中

不确定setPasswordToken()中设置的值未保存到数据库中的情况。有什么建议吗?

请参阅。您遇到的问题是脏检查,这在GORM 6.1中已更改

考虑一下这个代码

class Person {
    String name
    String email

    void updateName(String newName) {
        this.name = newName
    }

    static constraints = {
        email email: true
    }
}
updateName
方法不会导致
name
属性被标记为脏属性。以下代码将导致
name
属性被标记为脏:

class Person {
    String name
    String email

    void updateName(String newName) {
        setName newName
    }

    static constraints = {
        email email: true
    }
}
如果你真的想打开旧的脏检查方法,你可以按照我上面链接的评论中的说明来做,但是要注意这样做会带来性能损失。推荐的方法是使用setter或使用
markDirty
方法将属性显式标记为dirty

我希望这能有所帮助。

请参阅上的评论。您遇到的问题是脏检查,这在GORM 6.1中已更改

考虑一下这个代码

class Person {
    String name
    String email

    void updateName(String newName) {
        this.name = newName
    }

    static constraints = {
        email email: true
    }
}
updateName
方法不会导致
name
属性被标记为脏属性。以下代码将导致
name
属性被标记为脏:

class Person {
    String name
    String email

    void updateName(String newName) {
        setName newName
    }

    static constraints = {
        email email: true
    }
}
如果你真的想打开旧的脏检查方法,你可以按照我上面链接的评论中的说明来做,但是要注意这样做会带来性能损失。推荐的方法是使用setter或使用
markDirty
方法将属性显式标记为dirty


我希望这能有所帮助。

请参阅Graeme在的回答。是因为我使用自己的设置器而错过了脏支票吗?“是因为我使用自己的设置器而错过了脏支票吗?”-不是真的。问题是您的setter(
setPasswordToken
)正在使用
this.resetPasswordToken=(java.util.UUID.randomUUID()作为字符串)
进行字段访问。如果这是
setResetPasswordToken((java.util.UUID.randomuid()作为字符串))
,我希望它能工作。因为脏检查在
setResetPasswordToken
方法中,您没有使用它。太棒了!很高兴我能提供帮助。没有关系,但如果您将
setPasswordToken
方法名称更改为更具体的as
renewThePasswordToken
,您可以避免声明瞬态See Graeme的回答是。我之所以缺少脏检查是因为我使用自己的setter吗?“我之所以缺少脏检查是因为我使用自己的setter吗?”-不是真的。问题是您的setter(
setPasswordToken
)正在使用
this.resetPasswordToken=(java.util.UUID.randomUUID()作为字符串)
进行字段访问。如果这是
setResetPasswordToken((java.util.UUID.randomuid()作为字符串))
,我希望它能工作。因为脏检查在
setResetPasswordToken
方法中,您没有使用它。太棒了!很高兴我能提供帮助。不相关,但如果您将
setPasswordToken
方法名称更改为更具体的as
renewThePasswordToken
,您可以避免使用我的自定义setter中的setXXX来声明瞬态,工作正常!在我的自定义setter中使用setXXX工作正常!