2011-02-09 58 views
1

我正在使用Grails 1.3.6,并且遇到保存级联问题时出现问题。问题是具有两个父类的类。什么我试图简化版本是这样的: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,图书实例被保存在发布实例之前,导致错误“不空属性引用null或瞬时值:adhoc.Book.publisher“。

我已经尝试了各种不同的方式来定义关系,但很少成功。我已经尝试过临时保存,这确实有效,但是我可以看到,父表被更新为我保存子数据 - 即位置,作者和发布者都更新到版本1.(并且我想保留代码尽可能简单。)我想避免链接表。

任何建议感激地收到!

回答

2

好的,所以这里的关键是保存级联从父母到孩子。 Book对于Book来说有问题,因为Book对于Publisher和Author都是一个孩子。 GORM尝试保存位置,位置尝试保存作者,作者试图保存书籍但是保存失败,因为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项目与您的域名班在此保存加入。级联工作正如你所期望的那样。