Grails,我如何得到一个不能保存的对象

use*_*325 11 java grails groovy grails-orm

我是grails的新手,并尝试创建一个表单,允许用户更改与他/她的帐户相关联的电子邮件地址.

它要求用户输入他们当前的密码以及他们想要使用的新电子邮件地址.如果用户输入了错误的密码或无效的电子邮件地址,那么它应该使用适当的错误消息拒绝它们.

现在,可以通过grails中的约束来完成电子邮件验证,但密码更改必须与其当前密码相匹配.我已将此检查作为服务类的方法实现.

见下面的代码:

def saveEmail =
{
    def client = ClientUser.get(session.clientUserID)
    client.email = params.email
    if(clientUserService.checkPassword(session.clientUserID , params.password) ==false)
    {
        flash.message = "Incorrect Password"
        client.discard()
        redirect(action:'changeEmail')
    }    
    else if(!client.validate())
    {
         flash.message = "Invalid Email Address"
         redirect(action:'changeEmail')
    }
    else
    {
        client.save();
        session.clientUserID = null;
        flash.message = "Your email address has been changed, please login again"
        redirect(controller: 'clientLogin' , action:'index')
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我发现奇怪的是,如果我输入了一封无效的电子邮件,那么就不会保存更改(如预期的那样)但是如果我输入了错误的密码和有效的电子邮件,那么它会保存更改,甚至将它们写回到数据库,即使它会给出正确的"无效密码"错误消息.

我很困惑,所以在所有if/else if/else块中设置了断点,发现它按预期命中了第一个if语句而没有击中其他语句,所以它永远不会遇到对save()方法的调用,然而它无论如何都得救了.

经过一些研究后,我来到了discard()方法的文档中,您可以在上面的代码中看到它.所以我添加了这个,但仍无济于事.我甚至尝试使用discard然后再次从DB重新加载客户端对象,但仍然没有骰子.

这是非常令人沮丧的,我会感激任何帮助,因为我认为这肯定不是一个复杂的要求!

Joh*_*ham 10

Grails会在Web请求结束时关闭您的Hibernate会话,这将刷新已更改的对象.该对象已连接到您的Hibernate会话,因为您通过Hibernate(get())获取了它.如果您想避免刷新更改,则需要使用discard().

这是由失败的验证器自动完成的,这就是为什么您不必为验证失败而这样做的原因.

但是,您可以通过将此逻辑移动到其中一个ClientUser字段上的自定义验证器来简化代码,这会自动丢弃失败时的对象,或者使用Grails命令对象,这也可以封装验证逻辑.然后,您只需检查命令对象上的错误.


Rez*_*aul 6

使用get()方法以读写模式检索数据,所以如果你改变任何东西它将是persist.Use read()方法可以以只读模式检索数据,所以如果你改变什么,那么需要使用save()方法那将解决你的问题.

请查看此http://grails.org/doc/latest/guide/GORM.html#basicCRUD