简体   繁体   English

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

[英]Grails/Gorm: how to filter a list of domain objects without affecting the database

Say we have something like the standard Book domain object and bookCategory object. 假设我们有类似标准Book域对象和bookCategory对象的东西。 In my controller I want to return a subset of list of books to the view. 在我的控制器中,我想将书籍列表的子集返回到视图。 That subset is not achievable using a find query. 使用查找查询无法实现该子集。 When I try to filer the return object, it deletes relationships from the database! 当我尝试过滤返回对象时,它将从数据库中删除关系!

I tried this: 我尝试了这个:

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]
    }
}

The problem is that it permanently removes these books from the categories for all users from the database!!! 问题是它将从数据库中的所有用户的类别中永久删除这些书籍!!!

I tried putting the method in a service and using a readonly transaction, but this did not help. 我尝试将方法放入服务中并使用只读事务,但这没有帮助。

I assume that even if I copy all the categories and books into new list, they will still update the DB as they will still have the book IDs (which I need) 我假设即使我将所有类别和书籍复制到新列表中,它们仍将更新数据库,因为它们仍具有书籍ID(我需要)

Saving to the database when you dont say save() is very dangerous. 当您不说save()时保存到数据库是非常危险的。 is there a way to disable this feature completely? 有没有办法完全禁用此功能?

There is a fundamental flaw in your approach. 您的方法存在根本缺陷。 Do not modify your domain instances if you don't intend to have the changes persisted. 如果不想保留更改,请不要修改域实例。 Doing so is going to cause you headaches. 这样做会使您头痛。

Your domain model is suppose to be your system of record. 您的域模型应该是您的记录系统。 Any changes to it are suppose to be persisted. 对它的任何更改都应保留。

If you need to gather up data and manipulate it without having it reflected in your domain model then use a DTO (data transfer object) or similar pattern. 如果您需要收集数据并对其进行处理而又不将其反映在域模型中,请使用DTO(数据传输对象)或类似模式。

Simply calling .discard() will discard the changes you have made from being persisted when the session automatically flushes. 只需调用.discard()在会话自动刷新时将您所做的更改从持久保存中丢弃。

Instead of working against the framework, and disabling behavior, change your approach to be correct. 更改您的方法是正确的,而不是违反框架并禁用行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM