Grails/Gorm:如何在不影响数据库的情况下过滤域对象列表

Grails/Gorm:如何在不影响数据库的情况下过滤域对象列表,grails,gorm,Grails,Gorm,假设我们有标准的BookDomain对象和bookCategory对象。在我的控制器中,我希望将书籍列表的子集返回到视图中。使用find查询无法实现该子集。当我尝试对返回对象进行文件管理时,它会从数据库中删除关系 我试过这个: class BookCategory{ String name static hasMany = [books:Book] } class Book{ String title } def myController() { def

假设我们有标准的BookDomain对象和bookCategory对象。在我的控制器中,我希望将书籍列表的子集返回到视图中。使用find查询无法实现该子集。当我尝试对返回对象进行文件管理时,它会从数据库中删除关系

我试过这个:

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()时保存到数据库是非常危险的。有没有办法完全禁用此功能?

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

假设您的域模型是您的记录系统。对它的任何更改都将被持久化

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

只要调用
.discard()
,会话自动刷新时,您所做的更改就不会被持久化


与其违背框架,禁用行为,不如将方法更改为正确的方法。

听起来不错,但我该怎么做呢?我是否需要编写与我的域类完全相同的重复域类(字段对字段),但将它们存储在src下?这是一个很大的工作,因为我有大约40个域类,并希望以这种方式过滤其中的许多,每次我想更改一个域类,我必须记住更改“shaddow”域类。我假设我需要手动将每个字段从嵌套的域类复制到我的非域版本。这似乎需要做很多工作,特别是我上面的例子已经简化了很多。我尝试通过调用discard遍历所有对象,然后进行筛选,但是由于会话代理错误而失败。我不能这样做,因为我已经删除了我想放弃删除的对象。我有另一个想法-从我的控制器方法中调用另一个方法,该方法会引发运行时异常,然后我会捕获该异常。这可能会回滚chagnes,但保留我想要返回的对象?好吧,这么做很长一段时间,创建阴影对象,然后手动创建它们。另一种方法可能是将过滤推迟到视图。在控制器中设置瞬态“禁止”,或在视图中通过标记进行检查。