2010-05-25 59 views
11

我是grails的新手,并试图创建一个表单,允许用户更改与他/她的帐户关联的电子邮件地址,我为他创建的网站。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') 
    } 
} 

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

我很困惑,所以在所有if/else if/else块中设置了断点,并发现它按预期击中了第一条if语句并且没有击中其他语句,所以它绝不会碰到保存的调用()方法,但它仍然保存。

一点点研究,我得出翻过文档,你可以在上面的代码看惯丢弃()方法。所以我加了这个,但仍然无济于事。我甚至尝试使用丢弃,然后再次从数据库重新加载客户端对象,但仍然没有骰子。

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

+0

client.discard()应该是这样做的方式,你可以在集成测试中重现问题吗? 您使用的是哪个版本的Grails? – leebutts 2010-05-25 21:28:28

+0

我刚刚尝试过对代码进行集成测试,奇怪的是,它似乎表现得像我想要的,但是当我通过网络正常进行时,我又遇到了同样的问题。 我会发布我的测试代码,但我不知道如何做到这一点,它告诉我,这是太多的字符 – user350325 2010-05-27 21:34:25

+0

你应该接受下面的答案! – oligofren 2011-05-03 14:54:58

回答

10

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

这是由一个失败的验证器自动完成的,这就是为什么你不必为验证失败而做它。

但是,通过将此逻辑移动到您的ClientUser字段之一上的自定义验证器(可自动丢弃发生故障的对象),或通过使用Grails命令对象(也可封装验证逻辑。然后你只需检查命令对象上的错误。

+0

是的,但这就是让我感到困惑,我正在使用丢弃,这是在集成测试,但不在网络上 – user350325 2010-05-27 21:35:04

+1

请记住,集成测试最终回滚您的交易。在网络上,您的交易最终会落实。 – 2010-05-29 20:16:24

0

你只是在做闪存,这与回滚事务无关。 如果发生错误,则抛出RuntimeException,并且它将回滚对数据库的更改。

5

使用get()方法检索读写模式数据,所以如果你改变什么这将是persist.Use阅读()方法可以在只读模式下检索数据,所以如果你改变什么,然后需要使用save()方法。这将解决你的问题。

看看这个http://grails.org/doc/latest/guide/GORM.html#basicCRUD

+0

这对我有用,但我不明白为什么丢弃不起作用,如果你使用得到,谢谢反正 – sttaq 2014-11-20 11:09:23

0

的R & d后,我弄清楚,我们需要明确就像整个过程:

session.clear() 

按照documentation

完全清除会话。逐出所有已加载的实例并取消所有未决的保存,更新和删除操作 。不要关闭打开迭代器 或ScrollableResults的实例。

我们需要正确地清理休眠会话。结果会话将返回到可用状态,并在将来使用时不会受到早期错误的影响。

相关问题