如何防止Grails finder方法保存我的对象?

时间:2015-02-26 18:45:48

标签: hibernate grails transactions gorm spring-transactions

我有一台Grails 2.4.4控制器:

class FooController {
    def fooService

    @Transactional
    def save(Foo foo) {
         def duplicateFoos = fooService.duplicateFoos(foo)
         if (duplicateFoos) {
              flash.error = "Duplicate foos exist: $duplicateFoos"
              render(model: foo, view: 'create')
         } else { /* ... */ }
    }

服务也很简单

@Transactional
class FooService {
    def duplicateFoos(Foo foo) {
        log.info(foo) // here foo has no ID
        JobAssignment.findAllBySomeProperty(foo.someProperty)
        log.info(foo) // here new ID is assigned to foo
    }
}

Foo到达未保存且没有ID进入duplicateFoos方法,但在执行后,它突然带有ID并保存在数据库中(从日志语句中可以看出)。

我有

dataSource {
    flush.mode = 'manual'
}
DataSource.groovy中的

我手动尝试

sessionFactory.currentSession.transaction.rollback()

sessionFactory.currentSession.transaction.rollback()        
sessionFactory.currentSession.transaction.begin()
FooController中的

。在这种情况下,ID仍会在findAllBySomeProperty阶段分配(不确定原因),但它不会持久保存到数据库。但是,我得到org.hibernate.TransactionException: Transaction not successfully started

我还尝试手动设置sessionFactory.currentSession.flushMode = FlushMode.MANUAL,虽然它似乎有助于这个特定的位置(没有分配新ID),但其他后来的代码并没有调用save(或者任何)对象仍然保存它。我也不认为在每个交易方法的开头都有flushMode = MANUAL是一个很好的解决方案。

我现在只是抛出一个Exception - 确保没有任何东西被保存。这显然不是一个好的解决方案,因为我需要重定向回到表单。

那么当我打电话给.save时,我怎样才能强制保存对象?

或者,如果无法做到这一点,如何在仍然能够重定向到某个屏幕的同时干净地回滚事务?

P.S。我回顾了一堆可能相关的Grails JIRA,但我没有找到解决问题的方法:


@BurtBeckwith,是的,Foo belongsTo Bar和Bar hasMany Foo-s(两者都是标准的Grails域对象)。

但是,我不会在这些方法中操作Bar-s。我所做的只是:

def createForBar(Long barId) {
    Bar bar = Bar.findById(barId)
    Foo foo = new Foo(bar: bar)
    render(view: 'create', model: createModel(foo))
}

然后create表单有一个按钮,可以调用前面提到的save


@JeffScottBrown - 它是POST,创建新的id时没有Foo参数。

我通过了

<input type="hidden" name="bar.id" value="${fooInstance?.bar?.id}"/>

虽然。

0 个答案:

没有答案