我正在使用Grails 2.4.2。我正在保存违反约束的域类实例,所以我希望保存失败。但它似乎成功了。 Grails文档说明:
要记住的另一件事是Grails每次保存时都会验证域实例。如果验证失败,域实例将不会持久保存到数据库。
域类:
class Book {
String name
static constraints = {
name unique: true
}
String toString() { "[Book: id=${id} name=${name}]" }
}
以下代码修改第二个实例,使其与第一个实例具有相同的名称并尝试保存它(book3.save)。我希望这会失败,它确实返回null。但后来我通过Id(Book.get(book2.id))加载了同一个对象,并发现它有新名称。最后,它打印整个书籍列表,我们发现它们都有相同的名称。
def book1 = new Book(name: "Cats").save()
def book2 = new Book(name: "Dogs").save()
log.info "The books: ${Book.list()}"
def book3 = Book.get(book2.id)
book3.name = "Cats"
def book3save = book3.save() // Should fail?
def book4 = Book.get(book2.id)
log.info "The result of saving book ${book2.id} with name 'Cats' is ${book3save}"
log.info "The book with ID ${book2.id} is now named ${book4.name}"
log.info "The books are: ${Book.list()}"
输出:
The books: [[Book: id=1 name=Cats], [Book: id=2 name=Dogs]]
The result of saving book 2 with name 'Cats' is null
The book with ID 2 is now named Cats
The books are: [[Book: id=1 name=Cats], [Book: id=2 name=Cats]]
答案 0 :(得分:0)
默认情况下,Grails不会在验证错误上抛出异常。你可以做到
book3.save(failOnError: true)
将抛出异常。
或者您需要检查save()的返回值。 null表示验证失败。您还可以执行book3.validate()以在尝试保存之前查看实例是否有效。
我认为你所看到的正在更新的书的外观是由于hibernate会话。您的保存失败但是对Book.get()的调用从当前的hibernate会话而不是数据库加载实例。如果检查脏标志,则可以确认此检查isDirty()或调用refresh()以从数据库中重新获取实例。