1

次の 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 が本を保存しないようにする最善の方法は何ですか? または、検証が失敗したときに、データ バインディングによって行われた関連付けが適切にロールバックされないのはなぜですか?

4

1 に答える 1

0

サービスがトランザクション対応であることを指定した場合、例外がキャッチされないと、サービス メソッド内でトランザクションがロールバックされます。RDBMS が真のトランザクション/ロールバックをサポートしていない場合にのみ、邪魔になる可能性があります。

サービスがトランザクションかどうかを指定しましたか? サービスがトランザクション対応であることを宣言するには、次のようなステートメントが必要です。

def transactional = true
于 2011-05-27T14:10:01.550 に答える