【发布时间】:2021-12-31 11:03:15
【问题描述】:
使用 Grails 4.0.11 和 OpenJDK 11,我遇到了一个非常奇怪的行为,我可以将其提取到一个独立项目中,并确保它与插件无关:
Given 是一个控制器:
def updateOrder() {
def order = Order.get(params.id)
def result = shopService.setOrderPrintFileChecked(order)
redirect(action: "detailOrder", id: order.id)
}
和服务
@Transactional
class ShopService {
def setOrderPrintFileChecked(Order order) {
order.printFileChecked = new Date()
println("Validate: " + order.validate())
println("Errors: " + order.errors)
println("Dirty: " + order.isDirty())
def r = order.save(failOnError: true)
println("Result: " + r.printFileChecked)
return true
}
}
这不会将值保存到数据库中(尝试 MySQL+H2 默认数据库)。 如果显示:
Validate: true
Errors: org.grails.datastore.mapping.validation.ValidationErrors: 0 errors
Dirty: true
Result: Sun Nov 21 15:58:17 CET 2021
如果我将 ShopService 的方法从 setOrderPrintFileChecked() 更改为 setorderPrintFileChecked() 甚至 test(),它会起作用并且值正在正确保存。**
似乎前缀 + camelCase "setXyz" 有不同的行为。我想知道它是什么以及如何修复/防止这种情况。可以提供完整的演示应用程序的行为。
** 更新** 这是一个非 setter 名称的反编译服务类:
public Object updateMyValue(final Order order) {
final Reference order2 = new Reference((Object)order);
final CustomizableRollbackTransactionAttribute $transactionAttribute = new CustomizableRollbackTransactionAttribute();
$transactionAttribute.setName("ch.pacdesigner.ShopService.updateMyValue");
final GrailsTransactionTemplate $transactionTemplate = new GrailsTransactionTemplate(this.getTransactionManager(), $transactionAttribute);
return $transactionTemplate.execute((Closure)new ShopService._updateMyValue_closure1((Object)this, (Object)this, order2));
}
这是编译后的方法
public Object setOrderPrintFileChecked(final Order order) {
final CallSite[] $getCallSiteArray = $getCallSiteArray();
ScriptBytecodeAdapter.setGroovyObjectProperty($getCallSiteArray[0].callConstructor((Object)Date.class), (Class)ShopService.class, (GroovyObject)order, (String)"printFileChecked");
$getCallSiteArray[1].call((Object)order, (Object)ScriptBytecodeAdapter.createMap(new Object[] { "failOnError", true }));
return true;
}
【问题讨论】:
-
我刚刚遇到了一个类似的问题,所以我猜这与 Grails 修改设置器以处理脏检查有关。如果您想进一步检查它,请谷歌“grails setter dirty”。我会尝试 order.setPrintFileChecked(new Date()) 看看这是否适用于所有示例。
-
反编译的“setOrderPrintFileChecked”方法里面有事务管理指令吗?
-
@JeffScottBrown 我尝试了不同的方法名称,但方法始终相同,命名为“setOrderPrintFileChecked”或“holaSullivan”。如果我将“@Transactional”添加到方法头,它可以与“setOrderPrintFileChecked”一起使用——但如果我将它添加到服务中,它应该对任何方法都有效。如果我添加“withTransaction”块,它也可以工作。但这不是 DRY IMHO 的想法。
-
"我尝试了不同的方法名,方法总是一样" -
setOrderPrintFileChecked中的反编译指令中是否有事务管理逻辑? -
您没有显示足够的代码来确定,但看起来您正在开始事务之前从数据库中检索实体。是这样吗?
标签: grails grails-orm