2011-02-09 14 views
1

Grails 1.3.6を使用していますが、正しくカスケードするための保存に問題があります。この問題は、具体的には2つの親クラスを持つクラスで発生します。私がしようとしています何の簡易版はこれです:Grails/GORMが間違った順序で保存されます

class Location { 
    String city 
    static hasMany = [authors: Author, publishers: Publisher] 
} 

class Author { 
    String name 
    static belongsTo = [location: Location] 
    static hasMany = [books: Book] 
} 

class Publisher { 
    String name 
    static belongsTo = [location: Location] 
    static hasMany = [books: Book] 
} 

class Book { 
    String title 
    static belongsTo = [author: Author, publisher: Publisher] 
} 

class Srv1Service { 

    static transactional = true 

    def loadData() { 
     def l1 = new Location(city: "London") 

     def a1 = new Author(name: "Graham Greene") 
     l1.addToAuthors(a1) 

     def p1 = new Publisher(name: "Some Press") 
     l1.addToPublishers(p1) 

     def b1 = new Book(title: "The Comedians") 
     a1.addToBooks(b1) 
     p1.addToBooks(b1) 

     l1.save() 
    } 
} 

私はloaddataの上で実行した場合、Bookインスタンスが「非NULLプロパティがnullまたは一時値を参照するエラーが生じ、パブリッシャーのインスタンスの前に保存されます:adhoc.Book.publisher "

私はほとんど成功していない関係を定義するさまざまな方法を試しました。私は中間保存を試みましたが、これはうまくいきますが、子データを保存するときに親テーブルが更新されていることがわかります。つまり、Location、Author、およびPublisherはすべてバージョン1に更新されます。私はできるだけシンプルです)テーブルをリンクしないようにしたいと思います。

アドバイスをいただきありがとうございます。

答えて

2

ここで重要なことは、セーブが親から子までカスケードされていることです。 BookはPublisherとAuthorの両方の子であるため、Bookには問題があります。 GORMは場所を保存しようとします。場所は作成者を保存しようとします。著者は書籍を保存しようとします。BUT Bookは一時的な発行者を持つため、保存に失敗します。

def loadData() { 
    def l1 = new Location(city: "London") 

    def a1 = new Author(name: "Graham Greene") 
    l1.addToAuthors(a1) 

    def p1 = new Publisher(name: "Some Press") 
    l1.addToPublishers(p1) 
    l1.save() // add this save 

    def b1 = new Book(title: "The Comedians") 
    a1.addToBooks(b1) 
    p1.addToBooks(b1) 

    l1.save() 
} 

私はあなたのドメインクラスは、このセーブで追加することでローカルのGrailsプロジェクトを作成しました:あなたはあなたのブックを作成する前に、右のセーブ中間を追加

してみてください。カスケーディングは期待通りに機能しています。

関連する問題