2010-05-25 51 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的實例。

我們需要正確地清理休眠會話。結果會話將返回到可用狀態,並在將來使用時不會受到早期錯誤的影響。

相關問題