2012-05-01 13 views
4

比較的シンプルなGrailsプロジェクトでカスケード削除動作を生成するための正しい設定を作成するのに苦労しています。Grails(GORM)多対1カスケード削除動作

は、私は次のような単純なドメインクラスがあるとしましょう:

class Author { 
    String name 
    static constraints = { 
    } 
} 

class Book { 
    String title 
    Author author 
    static constraints = { 
    } 
} 

私は著者を作成し、その著者によって書かれた本を作成した場合、私は削除することはできませんよ最初に手作業で本を削除することなく作成者。私は "無条件の制約違反"を取得します。これは驚くべきことではありません。私の基礎となるデータベースであるMySQLは、 "本"テーブルの "著者"列の "外部キー制約"を "Restrict"としてGrailsによって作成されています(この動作はGrails私が理解しているようにドキュメンテーション)。

ブックテーブルの「作成者」列の基になるデータベースの制約を「制限」から「カスケード」に手動で変更する場合は、必要な動作が得られます。つまり、著者を削除すると、すべての書籍も削除されます。

私がしたいのは、著者列の "on delete cascade"を持つ "book"テーブルを作成する方法でGrails "Book"クラスを変更することです。私は、この種のことについての情報や、 "belongsTo"と明示的な "マッピング"を使ったGORMのデフォルトについてたくさんの情報を読んできました。これにより、それを作る

static belongsTo = [author: Author] 

Author author 

:「belongsToの」のドキュメントに基づいてこれを行うには

一つの方法は、からBookクラスに行を変更するように見えました著者が関係の「所有側」であることを明示している。ドキュメントは、これがカスケード削除動作を生成するはずであることを示唆しているようです。しかし、明示的な "hasMany = [books:Book]"をAuthorクラスに追加しない限りうまくいきません。私はこれをしたくない。 (この願いは、私の実際のビジネスドメインではより理にかなっていますが、理解の練習と同じように、著者のドメインクラスに明示的に書籍を知ってもらう必要はありません。

私は、Authorクラスを変更することなく、データベースのカスケード削除設定を生成するようにBookクラスを変更するgrails設定をしたいと思います。

static mapping = { 
     author cascade: 'all' 
} 

およびその他の明示的なマッピングまたは「belongsToの」オプションを持つこのの組み合わせ:私は次のように明示的なマッピングを使用してみました。これはうまくいかなかった。

基本SQLデータベースの「制約」を単純に変更して、私が望む動作が得られることに注目して、Grailsを使用してこれを取得する方法はありますか?そうでない場合、私はここで何か基本的なことを誤解しているのですか、何か愚かなことをしようとしていますか?

+0

Grailsのどのバージョンをお使いですか? –

答えて

2

書籍著者の必須フィールドが不足していると思います。

ここドキュメント(テストと作品)ごとにあるサンプルコード、

class Author { 

    String name 
    Book book //you are probably missing this field 

    static constraints = { 
    } 
} 

class Book { 

    String name 

    static belongsTo = [author: Author] 

    static constraints = { 
    } 
} 

テストケースです:

@TestFor(Author) 
@Mock([Book]) 
class AuthorTests { 

    @Test 
    void testAuthorBookCascades() { 

     Author a = new Author(name: "Douglas Adams") 
     Book b = new Book(name: "So Long, and Thanks for all the Fish") 
     a.book = b 
     a.save() 

     assert Author.count() == 1 
     assert Book.count() == 1 

     a.delete() 

     assert Author.count() == 0 
     assert Book.count() == 0 
    } 
} 

あなたが見ることができるように、あなたがブック引数を必要とするが、著者。 hasManyまたはhasOne節は必要ありません。

+0

Segarさんに感謝します。しかし、著者のクラス/テーブルを変更する必要はありません。ブックテーブルのカスケード動作を変更するだけです。しかし、あなたはこれがうまくいくことが正しいです(それを概説する努力に感謝します)。私は、あなたが言ったことが「正しい」方法であると思うかもしれないと思っています。私が求めているのは、すぐに使えるGORMで設計されていないということです。 – Glennn

+0

@Glennnはい、あなたはそれがあってはならないので、あなたが求めるものは定義されていません。これは、休止状態があなたが指定しなかった制約を作成し、すべてがカスケード削除を望んでいないことを意味します。 – GalmWing

+0

@Glennn - 外部の制約がある場合は、希望するカスケードのような動作を実行する削除用の独自の関数を記述するのが最善です。 GORMが関わっている限り、GalmWingは正しいと言います。 –

関連する問題