Grails 3.1 json 渲染
Grails 3.1 json rendering
我刚刚将我的应用程序从 grails 3.0.13 升级到 grails 3.1.1。在这样做的过程中,我在 JSON 渲染方面遇到了一个有趣的问题。
我一直在使用自定义 JSON 编组器:
JSON.registerObjectMarshaller(Appointment) { Appointment appointment ->
[
id: appointment.id,
version: appointment.version,
resourceChangeable: appointment.resourceChangeable,
start: appointment.startTime.format("yyyy-MM-dd'T'HH:mm:ss"),
end: appointment.endTime.format("yyyy-MM-dd'T'HH:mm:ss"),
displayStartTime: appointment.displayStartTime,
displayEndTime: appointment.displayEndTime,
title: appointment.description,
customerId: appointment.customerId,
customerName: appointment.customer?.fullName,
customerPhone: appointment.customer?.cellPhone,
resourceId: appointment.resourceId,
resourceName: appointment.resource?.name,
editUrl: appointment.editUrl,
updateUrl: appointment.updateUrl,
errors: appointment.errors,
eventBackgroundColor: appointment.resource?.backgroundColor,
notes: appointment.notes
]
}
当我尝试在 grails 3.1.1 中使用它时,出现以下错误:
No Datastore Session bound to thread, and configuration does not allow creation of non-transactional one here. Stacktrace follows:
org.grails.web.converters.exceptions.ConverterException: java.lang.IllegalStateException: No Datastore Session bound to thread, and configuration does not allow creation of non-transactional one here
at grails.converters.JSON.value(JSON.java:184) ~[grails-plugin-converters-3.1.1.jar:3.1.1]
at grails.converters.JSON.convertAnother(JSON.java:144) ~[grails-plugin-converters-3.1.1.jar:3.1.1]
at grails.converters.JSON.value(JSON.java:184) ~[grails-plugin-converters-3.1.1.jar:3.1.1]
at grails.converters.JSON.render(JSON.java:119) ~[grails-plugin-converters-3.1.1.jar:3.1.1]
at grails.converters.JSON.render(JSON.java:132) ~[grails-plugin-converters-3.1.1.jar:3.1.1]
at grails.artefact.controller.support.ResponseRenderer$Trait$Helper.render(ResponseRenderer.groovy:191) ~[grails-plugin-controllers-3.1.1.jar:3.1.1]
at se.easycalendar.admin.CalendarController.getAppointments(CalendarController.groovy:39) ~[main/:na]
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.groovy:53) ~[spring-security-core-3.0.3.jar:na]
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.groovy:62) ~[spring-security-core-3.0.3.jar:na]
at grails.plugin.springsecurity.web.SecurityRequestHolderFilter.doFilter(SecurityRequestHolderFilter.groovy:58) ~[spring-security-core-3.0.3.jar:na]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_72]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_72]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_72]
Caused by: java.lang.IllegalStateException: No Datastore Session bound to thread, and configuration does not allow creation of non-transactional one here
at BootStrap$_closure1$_closure3.doCall(BootStrap.groovy:30) ~[main/:na]
... 13 common frames omitted
它出现在 appointment.resource?.name 行。我尝试了不同的方法来解决这个问题,并成功地解决了一个用例,但现在我在另一个地方遇到了同样的错误。在任何地方都改变这个似乎是错误的做法。
在我的域中 class 我声明了这样的关系:
class Appointment {
String uuid = UUID.randomUUID().toString()
Date startTime
Date endTime
String description
String notes
Boolean resourceChangeable = true
Date dateCreated
Date lastUpdated
static belongsTo = [resource: Resource, customer: Customer, serviceEntityResource: ServiceEntityResource, sms: Sms]
static constraints = {
customer nullable: true
uuid maxSize: 40
serviceEntityResource nullable: true
description maxSize: 100
notes maxSize: 500, nullable: true, blank: true
sms nullable: true
}
static mapping = {
startTime index: 'appointment_start_time_idx'
sms cascade: 'none'
sort "startTime"
customer fetch: 'join'
resource fetch: 'join'
}
}
所以我认为我应该急切地加载资源和客户字段? (我以前在 grails 3.0.14 用户 "customer lazy: false" 中工作过。
不过现在不行了。那么会话在 gorm 5 中的工作方式有变化吗?我需要做什么才能继续在 json 渲染中使用关系?
我在这里找到了我自己问题的答案,并认为我应该 post 结果,以防其他人遇到同样的问题。
这个问题是因为我的 JSON 编组器。我使用了以下内容:
JSON.registerObjectMarshaller(Appointment) { Appointment appointment ->
[
id: appointment.id,
version: appointment.version,
resourceChangeable: appointment.resourceChangeable,
start: appointment.startTime.format("yyyy-MM-dd'T'HH:mm:ss"),
end: appointment.endTime.format("yyyy-MM-dd'T'HH:mm:ss"),
displayStartTime: appointment.displayStartTime,
displayEndTime: appointment.displayEndTime,
title: appointment.description,
customerId: appointment.customerId,
customerName: appointment.customer?.fullName,
customerPhone: appointment.customer?.cellPhone,
resourceId: appointment.resourceId,
resourceName: appointment.resource?.name,
editUrl: appointment.editUrl,
updateUrl: appointment.updateUrl,
errors: appointment.errors,
eventBackgroundColor: appointment.resource?.backgroundColor,
notes: appointment.notes
]
}
问题出在以下几行:
customerId: appointment.customerId,
resourceId: appointment.resourceId,
他们在 grails 3.0.x 中工作正常0.x,但在 grails 3.1.x 中不工作可能是因为切换到 gorm 5?无论如何,当我改为:
customerId: appointment.customer?.id,
resourceId: appointment.resource?.id,
一切正常!我觉得我不能使用 customerId 和 resourceId 属性(存储在约会本身)有点奇怪。我认为问题出在访问其他域对象上的模型的其他行,但事实并非如此。
我刚刚将我的应用程序从 grails 3.0.13 升级到 grails 3.1.1。在这样做的过程中,我在 JSON 渲染方面遇到了一个有趣的问题。
我一直在使用自定义 JSON 编组器:
JSON.registerObjectMarshaller(Appointment) { Appointment appointment ->
[
id: appointment.id,
version: appointment.version,
resourceChangeable: appointment.resourceChangeable,
start: appointment.startTime.format("yyyy-MM-dd'T'HH:mm:ss"),
end: appointment.endTime.format("yyyy-MM-dd'T'HH:mm:ss"),
displayStartTime: appointment.displayStartTime,
displayEndTime: appointment.displayEndTime,
title: appointment.description,
customerId: appointment.customerId,
customerName: appointment.customer?.fullName,
customerPhone: appointment.customer?.cellPhone,
resourceId: appointment.resourceId,
resourceName: appointment.resource?.name,
editUrl: appointment.editUrl,
updateUrl: appointment.updateUrl,
errors: appointment.errors,
eventBackgroundColor: appointment.resource?.backgroundColor,
notes: appointment.notes
]
}
当我尝试在 grails 3.1.1 中使用它时,出现以下错误:
No Datastore Session bound to thread, and configuration does not allow creation of non-transactional one here. Stacktrace follows:
org.grails.web.converters.exceptions.ConverterException: java.lang.IllegalStateException: No Datastore Session bound to thread, and configuration does not allow creation of non-transactional one here
at grails.converters.JSON.value(JSON.java:184) ~[grails-plugin-converters-3.1.1.jar:3.1.1]
at grails.converters.JSON.convertAnother(JSON.java:144) ~[grails-plugin-converters-3.1.1.jar:3.1.1]
at grails.converters.JSON.value(JSON.java:184) ~[grails-plugin-converters-3.1.1.jar:3.1.1]
at grails.converters.JSON.render(JSON.java:119) ~[grails-plugin-converters-3.1.1.jar:3.1.1]
at grails.converters.JSON.render(JSON.java:132) ~[grails-plugin-converters-3.1.1.jar:3.1.1]
at grails.artefact.controller.support.ResponseRenderer$Trait$Helper.render(ResponseRenderer.groovy:191) ~[grails-plugin-controllers-3.1.1.jar:3.1.1]
at se.easycalendar.admin.CalendarController.getAppointments(CalendarController.groovy:39) ~[main/:na]
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.groovy:53) ~[spring-security-core-3.0.3.jar:na]
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.groovy:62) ~[spring-security-core-3.0.3.jar:na]
at grails.plugin.springsecurity.web.SecurityRequestHolderFilter.doFilter(SecurityRequestHolderFilter.groovy:58) ~[spring-security-core-3.0.3.jar:na]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_72]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_72]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_72]
Caused by: java.lang.IllegalStateException: No Datastore Session bound to thread, and configuration does not allow creation of non-transactional one here
at BootStrap$_closure1$_closure3.doCall(BootStrap.groovy:30) ~[main/:na]
... 13 common frames omitted
它出现在 appointment.resource?.name 行。我尝试了不同的方法来解决这个问题,并成功地解决了一个用例,但现在我在另一个地方遇到了同样的错误。在任何地方都改变这个似乎是错误的做法。
在我的域中 class 我声明了这样的关系:
class Appointment {
String uuid = UUID.randomUUID().toString()
Date startTime
Date endTime
String description
String notes
Boolean resourceChangeable = true
Date dateCreated
Date lastUpdated
static belongsTo = [resource: Resource, customer: Customer, serviceEntityResource: ServiceEntityResource, sms: Sms]
static constraints = {
customer nullable: true
uuid maxSize: 40
serviceEntityResource nullable: true
description maxSize: 100
notes maxSize: 500, nullable: true, blank: true
sms nullable: true
}
static mapping = {
startTime index: 'appointment_start_time_idx'
sms cascade: 'none'
sort "startTime"
customer fetch: 'join'
resource fetch: 'join'
}
}
所以我认为我应该急切地加载资源和客户字段? (我以前在 grails 3.0.14 用户 "customer lazy: false" 中工作过。
不过现在不行了。那么会话在 gorm 5 中的工作方式有变化吗?我需要做什么才能继续在 json 渲染中使用关系?
我在这里找到了我自己问题的答案,并认为我应该 post 结果,以防其他人遇到同样的问题。
这个问题是因为我的 JSON 编组器。我使用了以下内容:
JSON.registerObjectMarshaller(Appointment) { Appointment appointment ->
[
id: appointment.id,
version: appointment.version,
resourceChangeable: appointment.resourceChangeable,
start: appointment.startTime.format("yyyy-MM-dd'T'HH:mm:ss"),
end: appointment.endTime.format("yyyy-MM-dd'T'HH:mm:ss"),
displayStartTime: appointment.displayStartTime,
displayEndTime: appointment.displayEndTime,
title: appointment.description,
customerId: appointment.customerId,
customerName: appointment.customer?.fullName,
customerPhone: appointment.customer?.cellPhone,
resourceId: appointment.resourceId,
resourceName: appointment.resource?.name,
editUrl: appointment.editUrl,
updateUrl: appointment.updateUrl,
errors: appointment.errors,
eventBackgroundColor: appointment.resource?.backgroundColor,
notes: appointment.notes
]
}
问题出在以下几行:
customerId: appointment.customerId,
resourceId: appointment.resourceId,
他们在 grails 3.0.x 中工作正常0.x,但在 grails 3.1.x 中不工作可能是因为切换到 gorm 5?无论如何,当我改为:
customerId: appointment.customer?.id,
resourceId: appointment.resource?.id,
一切正常!我觉得我不能使用 customerId 和 resourceId 属性(存储在约会本身)有点奇怪。我认为问题出在访问其他域对象上的模型的其他行,但事实并非如此。