次の 2 つのドメイン クラスがあるとします。
class Book {
String title
static hasMany = [authors: Author]
static belongsTo = Author
static constraints = {
title(nullable: false)
}
}
class Author {
static hasMany = [books: Books]
}
サービスでドメイン オブジェクトを作成して保持し、Grails のデータ バインディング機能を利用します。このようなメソッドは次のようになります。
def createAndPersistBook(params) throws ValidationException {
log.debug("Attempt to create and persist book")
Book book = new Book(params)
book.save(flush: true, failOnError: true)
log.debug("Created: ${book}")
book
}
params
地図を渡すと
params = ["authors": "[2]"]
service メソッド (タイトルが定義されていないため、検証は失敗します) に対して、新しく作成された書籍から既存の著者への関連付け (およびその逆) は、データ バインディングによって行われます。ただし、タイトルがnullable: false
定義されていないため、 aValidationException
がスローされ、トランザクションがロールバックされます。
ここで予想していたのは、書籍が保存されていないことですが、Book.list().isEmpty()
false が返されます。これは、休止状態によるダーティ チェックが原因であると考えられます。つまりbooks
、既存のコレクションauthor
が変更されて永続化され、この保存が book インスタンスにカスケードされます。
このシナリオで grails が本を保存しないようにする最善の方法は何ですか? または、検証が失敗したときに、データ バインディングによって行われた関連付けが適切にロールバックされないのはなぜですか?