在我的环境中,Config.groovy.上有grails.gorm.failOnError=true
package org.example
class Book {
String title
String author
String email
static constraints = {
title nullable: false, blank: false
email nullable: false, blank: false, unique: true //apparently this is the problem..
}
}
在控制器上,我有:
package org.example
class BookController {
def update() {
def bookInstance = Book.get(params.id)
if (!bookInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])
redirect(action: "list")
return
}
if (params.version) {
def version = params.version.toLong()
if (bookInstance.version > version) {
bookInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
[message(code: 'book.label', default: 'Book')] as Object[],
"Another user has updated this Book while you were editing")
render(view: "edit", model: [bookInstance: bookInstance])
return
}
}
bookInstance.properties = params
bookInstance.validate()
if(bookInstance.hasErrors()) {
render(view: "edit", model: [bookInstance: bookInstance])
} else {
bookInstance.save(flush: true)
flash.message = message(code: 'default.updated.message', args: [message(code: 'book.label', default: 'Book'), bookInstance.id])
redirect(action: "show", id: bookInstance.id)
}
}
}
保存是可以的。但是,当在没有设置标题字段的情况下更新时,我得到:
Message: Validation error whilst flushing entity [org.example.Book]:
- Field error in object 'org.example.Book' on field 'title': rejected value []; codes [org.example.Book.title.blank.error.org.example.Book.title,org.example.Book.title.blank.error.title,org.example.Book.title.blank.error.java.lang.String,org.example.Book.title.blank.error,book.title.blank.error.org.example.Book.title,book.title.blank.error.title,book.title.blank.error.java.lang.String,book.title.blank.error,org.example.Book.title.blank.org.example.Book.title,org.example.Book.title.blank.title,org.example.Book.title.blank.java.lang.String,org.example.Book.title.blank,book.title.blank.org.example.Book.title,book.title.blank.title,book.title.blank.java.lang.String,book.title.blank,blank.org.example.Book.title,blank.title,blank.java.lang.String,blank]; arguments [title,class org.example.Book]; default message [Property [{0}] of class [{1}] cannot be blank]
Line | Method
->> 46 | onApplicationEvent in org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 895 | runTask in java.util.concurrent.ThreadPoolExecutor$Worker
| 918 | run . . . . . . . in ''
^ 680 | run in java.lang.Thread
据我所知,问题发生在刷新hibernate会话时,hibernate试图再次保存对象,然后抛出异常。。。
当试图再次保存对象时,再次被称为book.validate((,它在数据库中进行新的查询,以确保电子邮件字段的唯一性。现在,抛出了Validation Exception。
但是,当我删除电子邮件属性的唯一验证时,更新会正常执行。。
我的问题是:这种行为是正确的吗?休眠呼叫簿。是否自动保存?
这是一个示例项目,模拟错误的步骤是:
- 来源:https://github.com/roalcantara/grails_app_validation_exception
- grails运行应用程序
- 导航到http://localhost:8080/book/book/create
- 创建一个填充所有字段的新实例
- 然后在http://localhost:8080/book/book/edit/1中编辑此实例
- 最后,删除"Title"字段并单击Update,然后抛出异常
在我的环境中,这种行为发生在grails 2.0.3和2.2.1版上
谢谢你的帮助!为我糟糕的英语感到抱歉。。rs./
您实际上要验证两次,第一次是使用:
bookInstance.validate()
第二个:
bookInstance.save(flush: true)
当您调用bookInstance.save(flush: true)
时,会返回一个boolean
。Grails在生成控制器时默认会利用这一点,但由于某种原因,您似乎已经更改了默认生成的控制器Grails。
只需替换此:
bookInstance.validate()
if(bookInstance.hasErrors()) {
render(view: "edit", model: [bookInstance: bookInstance])
} else {
bookInstance.save(flush: true)
flash.message = message(code: 'default.updated.message', args: [message(code: 'book.label', default: 'Book'), bookInstance.id])
redirect(action: "show", id: bookInstance.id)
}
有了这个:
if( !bookInstance.save( flush: true ) ) {
render(view: "edit", model: [bookInstance: bookInstance])
return
}