自定的錯誤訊息 使domain constraints 的檢查無效了?

33 views
Skip to first unread message

derekypp peng

unread,
Aug 15, 2010, 9:53:46 PM8/15/10
to grail...@googlegroups.com
大家好:
          又一個問題想請教大家


class CdApplicant {
            Date    birthday   //(必填)
    static constraints = {
                 birthday(blank:false,nullable:false)   //(必填)
   }
}

我有一個domain 裡面有一個birthday是一直要填值的
當我save()時 若沒有填值,就會丟一個flash.message 上面說 birthday  不能為null

            cdApplicantInstance.properties = params
            cdApplicantInstance.errors.rejectValue('birthday','自定錯誤訊息')   //自已多加的

            if (  !cdApplicantInstance.hasErrors() & cdApplicantInstance.save(flush: true)) {                                           
                flash.message = "${message(code: 'default.updated.message', args: [message(code: 'cdApplicant.label', default: 'CdApplicant'), cdApplicantInstance.name])}"
                redirect(action: "list")
            }

可是當我加了紅色那行自定錯誤訊息之後 就變成了
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Grails Runtime Exception

Error Details

Error 500: not-null property references a null or transient value: CdApplicant.birthday; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value: CdApplicant.birthday
Servlet: grails
URI: /child/grails/cdApplicant/update.dispatch
Exception Message: not-null property references a null or transient value: CdApplicant.birthday
Caused by: not-null property references a null or transient value: CdApplicant.birthday; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value: CdApplicant.birthday
Class: Unknown
At Line: [-1]
Code Snippet:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
雖然這個也是告訴我們brithday一定要填值,可以對user來說是一個系統壞掉的畫面
我以為會正常頁面會顯示
「自定錯誤訊息』和『birthday一定要填值』
但卻直接變Error 500

Tigerf

unread,
Aug 15, 2010, 10:23:30 PM8/15/10
to grail...@googlegroups.com
在grails中,使用new XXX(params) 或者 xxx.bindData(params) 是会自动触发validate的,其他方式赋值应该主动调用validate().
看这个错误应该是通过了hasErrors的检查,直接去保存了。为什么能通过hasErrors我也有点奇怪,毕竟你手动加进去了一个error。
我建议你使用i18n来自定义错误提示,比较省事的。

Thanks & Best Regards
Tiger Feng


2010/8/16 derekypp peng <dere...@gmail.com>

--
您收到此邮件是因为您订阅了 Google 网上论坛的“Grails联盟-GrailsUnion”论坛。
要向此网上论坛发帖,请发送电子邮件至 grail...@googlegroups.com
要取消订阅此网上论坛,请发送电子邮件至 grailsunion...@googlegroups.com
若有更多问题,请通过 http://groups.google.com/group/grailsunion?hl=zh-CN 访问此网上论坛。

derekypp peng

unread,
Aug 15, 2010, 10:59:53 PM8/15/10
to grail...@googlegroups.com
我剛剛又做一個測試:
class Aaa {
    String name
    Date   birthday

    static constraints = {
          //name(nullable:false,blank:false)                   //分別做String 和 Date 的實驗
          //birthday(nullable:false,blank:false)
    }
}

第一次做name因為他是String 所以和預想的結果一樣
加了 a.errors.rejectValue('name','自定錯誤訊息')  再去  if (  !a.hasErrors() && a.save(flush: true))  就丟出『自定錯誤訊息
若name為null的話,grails 也是乖乖導出 『 Property [name] of class [class test1.Aaa] cannot be blank 』
結果正常:成功導出『自定錯誤訊息』

第二次做birthday因為他是Date    ( 設定 birthday(nullable:false,blank:false) )
2-1. 第一種方法是
   只有在 if (  !a.hasErrors() && a.save(flush: true))之前加
   a.errors.rejectValue('birthday','自定錯誤訊息')  
  結果正常:成功導出『自定錯誤訊息』

2-2.第二種方法是
  if (  !a.hasErrors() && a.save(flush: true))之前加
   params.birthday = 'date.struct'            //自已假設birthday為空
   params.birthday_year = null
   params.birthday_month = null
   params.birthday_day = null
   a.errors.rejectValue('birthday','自定錯誤訊息')  
   結果正常:成功導出『自定錯誤訊息』

2-3.第三種方法是
  if (  !a.hasErrors() && a.save(flush: true))之前加
  def aaaInstance = Aaa.get(params.id)
  aaaInstance.properties = params
  aaaInstance.birthday = null            //自已假設birthday為空,但是改在instance的property

  結果失敗:grails 直接變error 500



最後大結論是:如果遇到date 又改了instance的property的話,hasErrors就會出問題
361.gif

Tigerf

unread,
Aug 15, 2010, 11:06:03 PM8/15/10
to grail...@googlegroups.com
第三种方法应该与date类型无关的。因为你修改property后没有主动调用validate(),所以errors就一直是空的。但是调用save()时会因为写入的数据不符合数据库的约束而throw一个SQLException,最后造成了error 500。
361.gif

derekypp peng

unread,
Aug 15, 2010, 11:38:22 PM8/15/10
to grail...@googlegroups.com
果然按Tigerf 大大說的一樣
我改一下流程變成

def aaaInstance = Aaa.get(params.id)
     aaaInstance.properties = params
     aaaInstance.validate()
     //下面才加自已的錯誤處理
    aaaInstance.errors.rejectValue('birthday','自定錯誤訊息')  

這樣不論是自已的錯誤處理或是原本設在domain的contransts都可以正常處理了
謝謝Tigerf  一語道破就問題的核心阿
唉我自已搞好久…
361.gif

Tigerf

unread,
Aug 16, 2010, 1:05:56 AM8/16/10
to grail...@googlegroups.com
嘿嘿,共勉。
361.gif
Reply all
Reply to author
Forward
0 new messages