我们注意到从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。经过一些调试后,我注意到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之前。如果我们删除注释并再次失败。
我们无法在任何其他控制器中看到该问题,也无法在小型测试项目中重现该问题。我们已经尝试重建项目,也是在一个我们不是的全新工作站上。
有没有人发现过这样的问题?
答案 0 :(得分:0)
我认为你甚至不需要在控制器中使用@Transactional(readOnly = true)。
Grails控制器默认为readOnly。您只需从控制器中删除注释即可。
相比之下,Grails服务类默认是事务性的。如果需要调用save()方法,则更希望在服务类中调用该方法。