Grails/GORM 以错误的顺序保存

发布于 2024-10-16 15:17:06 字数 1178 浏览 7 评论 0原文

我正在使用 Grails 1.3.6,但在正确级联保存时遇到问题。该问题特别针对具有两个父类的类。我正在尝试的简化版本是这样的:

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 实例将在 Publisher 实例之前保存,从而导致错误“not-null 属性引用 null 或瞬态值:adhoc.Book.publisher” 。

我尝试过各种不同的方式来定义这种关系,但收效甚微。我已经尝试过临时保存,这确实有效,但我可以看到父表在我保存子数据时更新 - 即位置、作者和出版商都更新到版本 1。(而且我也想保留代码尽可能简单。)我想避免链接表。

任何建议都将不胜感激!

I am using Grails 1.3.6 and I am having problems getting saves to cascade properly. The problem is specifically with classes that have two parent classes. A simplified version of what I am attempting is this:

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()
    } 
}

If I run the above loadData, the Book instance is saved before the Publisher instance, resulting in the error "not-null property references a null or transient value: adhoc.Book.publisher".

I have tried various different ways of defining the relationships with little success. I have tried interim saves, and this does work, but I can see that parent tables are updated as I save the child data - ie Location, Author and Publisher all get updated to version 1. (And also I would like to keep the code as simple as I can.) I would like to avoid linking tables.

Any advice is gratefully received!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

烟柳画桥 2024-10-23 15:17:06

好的,这里的关键是保存从父级到子级级联。当涉及到 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 项目,并将域类添加到此保存中。级联正在按您的预期工作。

Okay, so the key here is that saves are cascaded from parent to children. You have a problem when it comes to Book because Book is the child to both Publisher and Author. GORM tries to save Location, Location tries to save Author, Author tries to save Book BUT the save fails because Book has a transient Publisher.

Try adding an intermediate save right before you create your 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()
} 

I created a local Grails project with your domain classes adding in this save. The cascading is working as you would expect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文