用于保存域对象的Grails可重用服务

时间:2014-09-25 15:35:47

标签: grails

我有一个包含多个域类的Grails项目,我想通过在其中只有一个save()来使持久性服务尽可能可重用。为了尝试实现这一点,我在我的项目中完成了以下工作。

// PersistenceService.groovy

@Transactional
class PersistenceService {
def create(Object object) {        
    object.save flush: true
    object
}

// BaseRestfulController

class BaseRestfulController extends RestfulController {

def persistenceService

def save(Object object) {
    persistenceService.create(object)
}

// BookController的

class BookController extends BaseRestfulController {

private static final log = LogFactory.getLog(this)

static responseFormats = ['json', 'xml']

BookController() {
    super(Book)
}

@Transactional
def save(Book book) {
    log.debug("creating book")

    super.save(book)

}

所以基本上我有一堆域例如Author等,每个域都有自己的控制器,类似于bookController。那么有没有办法重用服务来实现持久性,就像我在上面尝试一样?

谢谢

1 个答案:

答案 0 :(得分:3)

我正在做类似的事情,但主要是因为我的所有实体实际上并未从数据库中删除,而是“标记”为已删除。对于多个应用程序,您需要这样的方法,因为它对于防止任何类型的数据丢失至关重要。

由于大多数数据库不支持此方案,因此在删除父项时,不能依赖外键删除依赖域实例。 所以我有一个名为GenericDomainService的基本服务类,它具有保存,删除(标记),取消删除(取消标记)的方法。

此服务提供可应用于任何域的基本实现。

class GenericDomainService {

def save( instance ) {
    if( !instance || instance.hasErrors() || !instance.save( flush: true ) ) {
        instance.errors.allErrors.each {
            if( it instanceof org.springframework.validation.FieldError ) {
                log.error "${it.objectName}.${it.field}: ${it.code} (${it.rejectedValue})"
            }
            else {
                log.error it
            }
        }
        return null
    }
    else {
        return instance
    }
}

def delete( instance, date = new Date() ) {
    instance.dateDisabled = date
    instance.save( validate: false, flush: true )
    return null
}

def undelete( instance ) {
    instance.dateDisabled = null
    instance.save( validate: false, flush: true )
    return null
}

}

然后,在我的控制器模板中,我总是声明两个服务:泛型和具体(可能不存在):

def ${domainClass.propertyName}Service
def genericDomainService

哪个会将名为Book的域转换为:

def bookService
def genericDomainService

在控制器方法中,我使用如下服务:

def service = bookService ?: genericDomainService
service.save( instance )

最后,给定域的服务将继承此服务,为这些操作提供(如果需要)自定义逻辑:

class BookService extends GenericDomainService {

def delete( instance, date = new Date() ) {
    BookReview.executeUpdate( "update BookReview b set b.dateDisabled = :date where b.book.id = :bookId and b.dateDisabled is null", [ date: date, bookId: instance.id ] )
    super.delete( instance, date )
}

def undelete( instance ) {
    BookReview.executeUpdate( "update BookReview b set b.dateDisabled = null where b.dateDisabled = :date and b.book.id = :bookId", [ date: instance.dateDisabled, bookId: instance.id ] )
    super.undelete( instance )
}

}

希望有所帮助。