【问题标题】:Grails/GORM domain saving - transient object workaroundGrails/GORM 域保存 - 瞬态对象解决方法
【发布时间】:2012-11-29 13:49:21
【问题描述】:

我找到了解决我遇到的问题的方法,我想知道它是否有效。这是一个类似的问题:Grails Gorm : Object references an unsaved transient instance

假设我有两个域对象(更改名称以保护有罪者)。

public class Shelf {
    String name
    Set<Book> books = [] as Set

    static hasMany = [books: Book]
}

和

public class Book {
    String title
    Shelf shelf
}

所以这意味着 1 个书架包含 0 到多本书,而一本书只能在一个书架上。

这个架子很大。在某个时候,它包含 80,000 本书。都很好地存储在数据库中。当然,添加新书越来越慢。

这是由以下人员完成的:

  Book book1 = new Book("Awesome Title")
  existingShelf.addToBooks(book1)
  existingShelf.save(flush: true)      // super slow

这很慢。主要是(我假设)因为 GORM 必须确认其他 80,000 条记录。

所以我这样做是为了解决这个慢点。

  Book book2 = new Book("Awesome Title 2")
  book2.save(flush: true)

这给了我一个“对象引用了一个未保存的瞬态实例”,我想这是有道理的——“货架”值是空的。

所以我做了一些有点奇怪的事情:

  Book book3 = new Book("Awesome Title 3")
  book3.shelf = new Shelf()
  book3.shelf.id = <known/valid id here>
  book2.save(flush: true)

这行得通。它节省。没有参考错误。取决于此的进一步代码......有效。 我只是在最后几分钟打了一个电话,然后把它缩短到几秒钟。 但这似乎太容易了。我确信我在某种程度上围绕着 Grails 魔法工作。并且可能在此过程中破坏了某些东西。

建议?解释?

【问题讨论】:

  • 你已经测试过Book book4 = new Book(title:"Awesome Title 4", shelf: existingShelf)的性能了吗?

标签: database grails grails-orm


【解决方案1】:

是的,使用 addTo* 方法可能会很慢。如果您查看生成的 SQL,您就会明白为什么。执行以下操作:

new Book(title: "GORM Performance", shelf: grailsShelf).save()

会更快,而且在技术上没有任何问题。请注意,在您从数据库刷新集合之前,您的 grailsS​​helf.books 实例不会包含新书。这是 addTo* 方法为您所做的一部分。

旁注:

Set<Book> books = [] as Set

没有必要。

【讨论】:

  • 在您应用到我的情况的示例中,grailsS​​helf 仅存在于方法的范围内。它没有被传递,所以我认为这不会是一个问题。当一个架子对象被使用时,它被“重新收集”。是的,SQL 语句令人印象深刻:)
  • 我基本上实现了你所说的,但是以一种“丑陋”的方式。感谢您确认我所做的事情。
猜你喜欢
  • 1970-01-01
  • 2012-05-06
  • 2010-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-06
相关资源
最近更新 更多