【问题标题】:Grails/Gorm: how to filter a list of domain objects without affecting the databaseGrails/Gorm:如何在不影响数据库的情况下过滤域对象列表
【发布时间】:2015-05-23 22:05:04
【问题描述】:

假设我们有标准的 Book 域对象和 bookCategory 对象。在我的控制器中,我想将书籍列表的子集返回到视图。使用查找查询无法实现该子集。当我尝试归档返回对象时,它会从数据库中删除关系!

我试过了:

class BookCategory{
     String name
     static hasMany = [books:Book]
}

class Book{
    String title
}

def myController() {
    def categories
    categories = BookCategory.list()
    def user = getCurrentUser()

    categories.each { category ->
         category.books.removeAll { book ->
             !isBookBannedForThisUser(book.title, user)
        }
    [bookCategories: categories]
    }
}

问题在于它会从数据库中所有用户的类别中永久删除这些书籍!!!

我尝试将方法放在服务中并使用只读事务,但这没有帮助。

我假设即使我将所有类别和书籍复制到新列表中,它们仍然会更新数据库,因为它们仍然具有书籍 ID(我需要)

当你不说 save() 时保存到数据库是非常危险的。有没有办法完全禁用此功能?

【问题讨论】:

    标签: grails grails-orm


    【解决方案1】:

    您的方法存在根本缺陷。 如果您不打算保留更改,请不要修改您的域实例。这样做会让您头疼。

    您的域模型应该是您的记录系统。对它的任何更改都应该被保留。

    如果您需要收集数据并对其进行操作而不将其反映在您的域模型中,请使用 DTO(数据传输对象)或类似模式。

    当会话自动刷新时,只需调用.discard() 将丢弃您所做的更改,以免被持久化。

    不要违背框架并禁用行为,而是改变你的方法以使其正确。

    【讨论】:

    • 听起来不错,但我该怎么做呢?我是否需要编写与我的域类完全相同的域类,但将它们存储在 src 下?这是很多工作,因为我有大约 40 个域类,并且想以这种方式过滤其中的许多,并且每次我想更改域类时,我都必须记住更改“影子”域类。我想我需要手动将嵌套域类中的每个字段复制到我的非域版本。看起来工作量很大,尤其是我上面的例子被简化了很多。
    • 我尝试循环遍历所有调用丢弃的对象,然后进行过滤,但由于会话代理错误而失败。之后我不能这样做,因为我已经删除了我想丢弃的对象。
    • 我有另一个想法 - 从我的控制器方法中调用另一个方法,该方法引发运行时异常,然后我将其捕获。这可能会回滚 chagnes,但保留我想要返回的对象?
    • 好的,做了很长的路,创建了阴影对象,然后手动构建了它们。
    • 另一种方法可能是将过滤推迟到视图。要么在控制器中设置一个瞬态“禁止”,要么通过标签在视图中检查它。
    猜你喜欢
    • 2023-01-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多