2

我们注意到在从 Grails 3.1.11 更新到 3.2.0 之后,控制器的一个操作不再起作用:

@Transactional(readOnly = true)
class RoomPlanController {
    ...
    def show(RoomPlan roomPlan) {
        ...
    }
    def getRooms(RoomPlan roomPlan) {
        ...
    }
}

问题是当我们调用时roomPlan/getRooms/1 roomPlan为空。如果我们调用show具有相同参数的动作 roomPlan 设置正确。

控制器内部的调用getErrors()会给我们以下错误消息:

无法获得当前的休眠会话;嵌套异常是 org.hibernate.HibernateException: No Session found for current thread

它起源于 grails.artefact.Controller.initializeCommandObject。经过更多调试后,我注意到和之间的堆栈跟踪有所show不同getRooms

堆栈跟踪show

show:100, RoomPlanController (at.byte_code.businessSuite.hotel)
$tt__show:-1, RoomPlanController (at.byte_code.businessSuite.hotel)
doCall:-1, RoomPlanController$_show_closure13 (at.byte_code.businessSuite.hotel)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)

堆栈跟踪getRooms

getRooms:109, RoomPlanController (at.byte_code.businessSuite.hotel)
getRooms:-1, RoomPlanController (at.byte_code.businessSuite.hotel)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)

错误消息和不同的堆栈跟踪让我们假设它与数据库会话/事务有关,并且在添加@Transactional(readOnly = true)到操作之后,一切都按预期工作,并且在更新到 grails 3.2.0 之前。如果我们删除注释并再次失败。

我们无法在任何其他控制器中看到该问题,也无法在小型测试项目中重现该问题。我们已经尝试重建项目,也在我们没有的全新工作站上。

有没有其他人观察到这样的问题?

4

1 回答 1

0

我认为您甚至不需要控制器中的 @Transactional(readOnly = true) 。

Grails 控制器默认是只读的。您可以简单地从控制器中删除注释。

相反,Grails 服务类默认是事务性的。如果需要调用 save() 方法,最好在服务类中调用该方法。

于 2016-10-10T15:47:32.343 回答