软删除Grails中的实体与Hibernate插件过滤器(Soft delete an entity

2019-09-22 12:47发布

我一直在寻找一种方法来避免数据库中删除我的用户,而是将它们标记为删除,不要把他们带回来的查询。

我发现这个插件http://grails.org/plugin/hibernate-filter ,这对任务的一大利器。

但是,当我试图执行我的解决方案,我通过其解决方案wheren't trought同样的问题(或者我是不是能找到)互联网上。

所以,接下来,我描述了我解决软删除的问题的方式。

Answer 1:

在这个例子中,我会让我的课的用户来处理它删除()方法为软删除,设置属性lowDate与实际日期时删除()调用的用户实例。 这个想法是,用户lowDate!= NULL将被GORM查询忽略。

1)Intall休眠过滤插件。 寻找在插件的页面的相关性: http://grails.org/plugin/hibernate-filter 。 看看文档。

2)添加到数据源如下:

import org.grails.plugin.hibernate.filter.HibernateFilterDomainConfiguration

environments {
    development {
    dataSource {
        ...    
        configClass = HibernateFilterDomainConfiguration
    }
    }
    test {
    dataSource {
        ...
        configClass = HibernateFilterDomainConfiguration
    }
    }
    production {
    dataSource {
        ...
        configClass = HibernateFilterDomainConfiguration
    }
    }   
}

3)在类定义过滤器:

class User {
    ...
    String email
    Date lowDate
    static hibernateFilters = {
        deletedFilter(condition:'low_date is null', default:true)
    }
    static constraints = {
        ...
        lowDate nullable: true
    }
    ...
}

注意:看我所规定的条件的方式。 它接收该值为SQL,所以要小心,因为它是数据库,而不是在类名上名的属性。

这将使GORM方法来避免将具有比lowDate空不同的用户。

4)的方式定义beforeDelele避免物理性缺失:

class User {
    ...
    def beforeDelete() {
        SecUser.executeUpdate("update SecUser su set lowDate = :lowDate where email = :email",
                                [lowDate: new Date(), email: email])
        return false
    }
}

注:我想一个简单的方法来实现beforeDelete(),这是

def beforeDelete() {
    this.lowDate = new Date()
    this.save()
    return false
}

但是,当保存()被调用内部beforeDelete,保存方法称为beforeDelete,等等,产生的StackOverflow。 我不知道为什么会这样。

5)使能自举滤波器:

class BootStrap {
    ...
    def init = { servletContext ->
        User.enableHibernateFilter('deletedFilter')
        environments {
            ...
        }
    }
...
}

这一切,显示它现在的工作。 为了测试后的功能,这里的一些样品斯波克测试:

注:“构建”的方法是从生成测试数据的插件。

class UserIntegrationSpec extends IntegrationSpec {

    def 'it should not find users marked as deleted'(){
        given: 'some users with lowDate and some withOut lowDate (=null)'
            User.build(firstName:'delUser1', lowDate: new Date())
            User.build(firstName:'user1')
            User.build(firstName:'delUser2', lowDate: new Date())
            User.build(firstName:'user2')
            def users = User.list()
        expect: 'it should only find the ones with lowDate == null'
            users.size() == 2
            users.every { it.firstName == 'user1' || it.firstName == 'user2' }      
    }

    def 'it should only delete users logically' (){
        given: 'a persisted user'
            def user = User.build(firstName: 'logiDelUser')
        when: 'user.delete() is called'
            user.delete(failOnError:true, flush:true)
            def deletedUser
            def users 
            User.withoutHibernateFilters(){
                users = User.list()
                deletedUser = User.find { firstName == 'logiDelUser' }
            }
        then: 'it should not delete the user from the DB, but set a low date instead'
            users.size() != 0
            deletedUser.lowDate != null
            deletedUser.firstName == 'logiDelUser' 
    }
}

希望帮助!



Answer 2:

另一种方法,使软删除在GORM实体使用以下插件:

http://grails.org/plugin/logical-delete

它使用“删除”标志为已删除和查询没有显示标记的实体。 该插件使用Hibernate的过滤器插件



文章来源: Soft delete an entity in Grails with Hibernate Filters Plugin