@Transactional未应用于所有控制器操作

时间:2016-10-08 12:11:42

标签: grails transactions spring-transactions grails3

我们注意到从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()会给我们以下错误消息:

  

无法获取当前的Hibernate会话;嵌套异常是org.hibernate.HibernateException:找不到当前线程的会话

它的起源是grails.artefact.Controller.initializeCommandObject。经过一些调试后,我注意到showgetRooms

之间的堆栈跟踪存在差异

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之前。如果我们删除注释并再次失败。

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

有没有人发现过这样的问题?

1 个答案:

答案 0 :(得分:0)

我认为你甚至不需要在控制器中使用@Transactional(readOnly = true)。

Grails控制器默认为readOnly。您只需从控制器中删除注释即可。

相比之下,Grails服务类默认是事务性的。如果需要调用save()方法,则更希望在服务类中调用该方法。