2012-09-17 19 views
3

我正在寻找一种方法来避免从DB中删除我的用户,而是将它们标记为已删除,并且不要将它们带回查询中。用Hibernate Filters Plugin删除Grails中的一个实体

我发现这个插件http://grails.org/plugin/hibernate-filter,这是一个伟大的任务工具。

但是当我试图实施我的解决方案时,我通过了在互联网上解决了哪些问题(或者我无法找到)的相同问题。

因此,接下来,我将描述我解决软删除问题的方法。

回答

5

在这个例子中,我将使我的类User将它的delete()方法作为软删除来处理,在用户实例上调用delete()时将属性lowDate设置为实际日期。这个想法是,具有lowDate!= null的用户将被GORM查询忽略。

1)Intall Hibernate Filter Plugin。在插件的页面查找依赖关系: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不同于null的用户。

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 { 
      ... 
     } 
    } 
... 
} 

这一切,现在表现出的工作。要测试函数的属性,下面是一些示例spock测试:

注意:'build'方法来自build-test-data插件。

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

希望这可以帮助!

+2

灿模型从关联进账? –

+1

长的时间,因为使用Grails :)编程,我应该做的规范检查。后来,我将尝试找到项目(希望对GH),并检查它。很好的问题BTW。 –

相关问题