未保存在域方法中设置的 Grails 3.3.10 值

Grails 3.3.10 value set in domain method is not being saved

我有一个具有 resetPasswordToken 属性的用户 class,这是在用户尝试重置密码时设置的 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,但不在数据库中。还检查了保存时的错误,没有错误。

奇怪的是,如果我在控制器中执行user.resetPasswordToken = "xxxx",该值会正确保存到数据库中。

不确定在 setPasswordToken() 中设置的值没有保存到数据库中是怎么回事。有什么指点吗?

请参阅 https://github.com/grails/grails-data-mapping/issues/961#issuecomment-309379214 中的评论。您遇到的问题是脏检查之一,它在 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 方法将 属性 显式标记为脏。

希望对您有所帮助。