I have a User class with a resetPasswordToken attribute, that is a UUID set when a user tries to reset his password.
On Grails 2.5.6 I had something like this that worked OK:
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)
}
}
Now I migrated that to GRails 3.3.10 and the resetPasswordToken is NULL on the database after the forgotPassword action is invoked. If I do a println after the user.setPasswordToken() is invoked, I can see the resetPasswordToken is set to an UUID, but is not in the DB. Also checked for errors on the save, and there are no errors.
Strange thing, if I do user.resetPasswordToken = "xxxx" in the controller, the value is saved into the database correctly.
Not sure what is going on with the value set in the setPasswordToken() not being saved into the DB. Any pointers?
See the comment at https://github.com/grails/grails-data-mapping/issues/961#issuecomment-309379214. The issue you are experiencing is one of dirty checking, which changed in GORM 6.1.
Consider this code...
class Person {
String name
String email
void updateName(String newName) {
this.name = newName
}
static constraints = {
email email: true
}
}
That updateName
method will not result in the name
property being marked as dirty. The following code would result in the name
property being marked as dirty:
class Person {
String name
String email
void updateName(String newName) {
setName newName
}
static constraints = {
email email: true
}
}
If you really want to turn on the old way of dirty checking you can do that per the instructions in the comment I linked above but be aware of the performance penalty of doing so. The recommended approach would be to use the setter or to explicitly mark the property as dirty using the markDirty
method.
I hope that helps.