服务中的Grails验证会导致静默回滚

时间:2013-01-14 13:49:24

标签: validation grails rollback

在Grails服务中,我根据外部列表创建/更新域实体。更新发生在循环中。如果输入文件中的行有效,则更新实体。否则,我会存储有问题的行号并处理下一行。

问题:当我在一个实体上调用validate()时,如果结果是false,那么在回滚的服务中完成的任何工作,即使与验证无关,虽然没有例外可见。例如:

assert contact.firstName = 'Bruce'
contact.firstName = 'John'
assert contact.save()
...
company.vat = 'bogus'
if (!company.validate()) {
    log.error "bogus"
    company.discard()
} else {
    assert company.save()
}
log.debug "done"

如果公司未验证,我的日志将显示“虚假”和“已完成”。联系人名字将在数据库中为'Bruce',而不是'John'

备用版本:如果我不致电company.validate(),则会更新联系人名字。

在这个阶段,我怀疑Grails将我的公司实例附加到validate()调用上,当它实现验证没有通过时执行事务,并且尽管discard()努力了。

从validate()语义及其javadoc(“验证实例”),我没有想到任何副作用,验证是否失败,或者我是否甚至调用了validate()。

你怎么看?这是一个“正常”的行为,还是一个错误?我该如何解决这个问题?

如果需要,我有一个简单的复制案例,有两个实体。

2 个答案:

答案 0 :(得分:0)

我可能在这里遗漏了一些东西,但不是'discard'方法的全部目标,不应用更改,以及您在此处看到的内容(在验证的情况下不应用更改)错误)是合乎逻辑的?

答案 1 :(得分:0)

无法在此设置中对其进行测试,但是您可以在服务中设置transactional = false,处理所有对象(在一个列表中添加正确验证的对象并在其他位置保存/记录失败的对象),然后最后保存使用withTransaction的“好”对象列表?类似的东西:

static transactional = false
def sessionFactory
List<Company> validCompanies = []
for(Company company: listOfCompaniesToValidate) {
    if (!company.validate()) {
        log.error "bogus"
    } else {
        validCompanies.add(company)
    }
}
Company.withTransaction {
    for (Company validCompany: validCompanies)
        validCompany.save()
    }
    validCompanies.clear()
}
sessionFactory.getCurrentSession().clear();

只是一个想法!