使用来自 grails 4.0.3 中的 rabbit mq 消费者的数据在服务层的数据库中保存记录时出现问题
Problems in saving records in database in service tier with data which comes from rabbit mq consumer in grails 4.0.3
我在将 RabbitMQ 队列与 Grails 4.0.3 一起使用时遇到了问题。和 JVM 版本:1.8.0_275
我不知道为什么,但我有一个兔子消费者,它必须做一些事情,其中包括将数据保存在数据库中,如下所示。
package br.gov.cmb.pid.consumers
import br.gov.cmb.pid.domain.RenachLog
import br.gov.cmb.pid.services.PidService
import com.budjb.rabbitmq.consumer.MessageContext
import com.budjb.rabbitmq.publisher.RabbitMessagePublisher
import grails.gorm.transactions.Transactional
import org.grails.web.json.JSONObject
@Transactional
class PidIssuingConsumer {
RabbitMessagePublisher rabbitMessagePublisher
static rabbitConfig = [ queue : "detran.transactions.191.requests" ]
JSONObject icomResp
def handleMessage(Map body, MessageContext messageContext) {
icomResp = new JSONObject().accumulate("status","No response available")
PidService pidService
try {
icomResp = sendPidIssuingToIcom(body as JSONObject)
publishIcomPidIssuingResponse(icomResp)
saveRenachLog(icomResp.toString())
} catch (Exception e){
saveRenachLog(e.getLocalizedMessage())
println(e.printStackTrace())
}
}
def sendPidIssuingToIcom(JSONObject pidIssuingDocument){
println(pidIssuingDocument)
return pidIssuingDocument
}
def publishIcomPidIssuingResponse(JSONObject pidIssuingResponse){
rabbitMessagePublisher.send {
exchange = "detran.requests"
routingKey = "191-response"
body = [response: pidIssuingResponse]
}
println(pidIssuingResponse)
}
def saveRenachLog(String icomResp){
RenachLog renachLog = new RenachLog()
renachLog.transactionId = "191"
renachLog.loggedOn = new Date()
renachLog.logDescription = icomResp
renachLog.save(flush: true, failOnError: true)
}
}
此代码按预期工作,但我希望在我的服务中将方法 saveRenachLog 和 sendPidIssuingToIcom 分开 PidService.groovy。不幸的是,当我这样做时,我收到了下面的异常消息。
本地化消息:
完成堆栈跟踪。
2021-11-03 12:06:52.399 错误 --- [pool-5-thread-1] c.b.r.consumer.AbstractConsumerContext:未处理的异常 java.lang.reflect.InvocationTargetException 在消费者 br.gov.cmb.pid.consumers.PidIssuingConsumer 的 RabbitMQ 消息处理程序中捕获
java.lang.reflect.InvocationTargetException: null
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.budjb.rabbitmq.consumer.LegacyConsumerContext.process(LegacyConsumerContext.groovy:262)
at com.budjb.rabbitmq.consumer.LegacyConsumerContext$process.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:156)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:168)
at com.budjb.rabbitmq.consumer.AbstractConsumerContext.deliverMessage(AbstractConsumerContext.groovy:325)
at com.budjb.rabbitmq.consumer.ConsumerContext$deliverMessage.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
at com.budjb.rabbitmq.consumer.RabbitMessageHandler.handleDelivery(RabbitMessageHandler.groovy:100)
at com.rabbitmq.client.impl.ConsumerDispatcher.run(ConsumerDispatcher.java:149)
at com.rabbitmq.client.impl.ConsumerWorkService$WorkPoolRunnable.run(ConsumerWorkService.java:104)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException: Cannot invoke method saveRenachLog() on null object
at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:91)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:43)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:34)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
at br.gov.cmb.pid.consumers.PidIssuingConsumer.$tt__handleMessage(PidIssuingConsumer.groovy:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1217)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1041)
at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:1011)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:994)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethodSafe(InvokerHelper.java:97)
at br.gov.cmb.pid.consumers.PidIssuingConsumer$_handleMessage_closure1.doCall(PidIssuingConsumer.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:263)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1041)
at groovy.lang.Closure.call(Closure.java:405)
at groovy.lang.Closure.call(Closure.java:421)
at grails.gorm.transactions.GrailsTransactionTemplate.doInTransaction(GrailsTransactionTemplate.groovy:94)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)
at grails.gorm.transactions.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:91)
at br.gov.cmb.pid.consumers.PidIssuingConsumer.handleMessage(PidIssuingConsumer.groovy)
... 20 common frames omitted
我已经在我的服务代码中插入了@Transactional。
你能帮帮我吗?
注意 1:当您将方法移至服务时,我无法判断代码是什么样子,您可能希望包含失败的代码。
也就是说,您似乎是在方法中声明 pidService,默认值为 null,然后尝试对其调用方法。
尝试改变这个:
RabbitMessagePublisher rabbitMessagePublisher
static rabbitConfig = [ queue : "detran.transactions.191.requests" ]
JSONObject icomResp
def handleMessage(Map body, MessageContext messageContext) {
icomResp = new JSONObject().accumulate("status","No response available")
PidService pidService
对此:
RabbitMessagePublisher rabbitMessagePublisher
PidService pidService
static rabbitConfig = [ queue : "detran.transactions.191.requests" ]
JSONObject icomResp
def handleMessage(Map body, MessageContext messageContext) {
icomResp = new JSONObject().accumulate("status","No response available")
注意 pidService 现在是 class 属性,不是方法局部变量。如果 PidService 是 Grails 中的另一个服务,那么它应该可以正常注入并可用。至少这应该清除您的 NullPointerException,并让您继续调试。
我在将 RabbitMQ 队列与 Grails 4.0.3 一起使用时遇到了问题。和 JVM 版本:1.8.0_275
我不知道为什么,但我有一个兔子消费者,它必须做一些事情,其中包括将数据保存在数据库中,如下所示。
package br.gov.cmb.pid.consumers
import br.gov.cmb.pid.domain.RenachLog
import br.gov.cmb.pid.services.PidService
import com.budjb.rabbitmq.consumer.MessageContext
import com.budjb.rabbitmq.publisher.RabbitMessagePublisher
import grails.gorm.transactions.Transactional
import org.grails.web.json.JSONObject
@Transactional
class PidIssuingConsumer {
RabbitMessagePublisher rabbitMessagePublisher
static rabbitConfig = [ queue : "detran.transactions.191.requests" ]
JSONObject icomResp
def handleMessage(Map body, MessageContext messageContext) {
icomResp = new JSONObject().accumulate("status","No response available")
PidService pidService
try {
icomResp = sendPidIssuingToIcom(body as JSONObject)
publishIcomPidIssuingResponse(icomResp)
saveRenachLog(icomResp.toString())
} catch (Exception e){
saveRenachLog(e.getLocalizedMessage())
println(e.printStackTrace())
}
}
def sendPidIssuingToIcom(JSONObject pidIssuingDocument){
println(pidIssuingDocument)
return pidIssuingDocument
}
def publishIcomPidIssuingResponse(JSONObject pidIssuingResponse){
rabbitMessagePublisher.send {
exchange = "detran.requests"
routingKey = "191-response"
body = [response: pidIssuingResponse]
}
println(pidIssuingResponse)
}
def saveRenachLog(String icomResp){
RenachLog renachLog = new RenachLog()
renachLog.transactionId = "191"
renachLog.loggedOn = new Date()
renachLog.logDescription = icomResp
renachLog.save(flush: true, failOnError: true)
}
}
此代码按预期工作,但我希望在我的服务中将方法 saveRenachLog 和 sendPidIssuingToIcom 分开 PidService.groovy。不幸的是,当我这样做时,我收到了下面的异常消息。
本地化消息:
完成堆栈跟踪。 2021-11-03 12:06:52.399 错误 --- [pool-5-thread-1] c.b.r.consumer.AbstractConsumerContext:未处理的异常 java.lang.reflect.InvocationTargetException 在消费者 br.gov.cmb.pid.consumers.PidIssuingConsumer 的 RabbitMQ 消息处理程序中捕获
java.lang.reflect.InvocationTargetException: null
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.budjb.rabbitmq.consumer.LegacyConsumerContext.process(LegacyConsumerContext.groovy:262)
at com.budjb.rabbitmq.consumer.LegacyConsumerContext$process.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:156)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:168)
at com.budjb.rabbitmq.consumer.AbstractConsumerContext.deliverMessage(AbstractConsumerContext.groovy:325)
at com.budjb.rabbitmq.consumer.ConsumerContext$deliverMessage.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
at com.budjb.rabbitmq.consumer.RabbitMessageHandler.handleDelivery(RabbitMessageHandler.groovy:100)
at com.rabbitmq.client.impl.ConsumerDispatcher.run(ConsumerDispatcher.java:149)
at com.rabbitmq.client.impl.ConsumerWorkService$WorkPoolRunnable.run(ConsumerWorkService.java:104)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException: Cannot invoke method saveRenachLog() on null object
at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:91)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:43)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:34)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
at br.gov.cmb.pid.consumers.PidIssuingConsumer.$tt__handleMessage(PidIssuingConsumer.groovy:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1217)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1041)
at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:1011)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:994)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethodSafe(InvokerHelper.java:97)
at br.gov.cmb.pid.consumers.PidIssuingConsumer$_handleMessage_closure1.doCall(PidIssuingConsumer.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:263)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1041)
at groovy.lang.Closure.call(Closure.java:405)
at groovy.lang.Closure.call(Closure.java:421)
at grails.gorm.transactions.GrailsTransactionTemplate.doInTransaction(GrailsTransactionTemplate.groovy:94)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)
at grails.gorm.transactions.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:91)
at br.gov.cmb.pid.consumers.PidIssuingConsumer.handleMessage(PidIssuingConsumer.groovy)
... 20 common frames omitted
我已经在我的服务代码中插入了@Transactional。
你能帮帮我吗?
注意 1:当您将方法移至服务时,我无法判断代码是什么样子,您可能希望包含失败的代码。
也就是说,您似乎是在方法中声明 pidService,默认值为 null,然后尝试对其调用方法。
尝试改变这个:
RabbitMessagePublisher rabbitMessagePublisher
static rabbitConfig = [ queue : "detran.transactions.191.requests" ]
JSONObject icomResp
def handleMessage(Map body, MessageContext messageContext) {
icomResp = new JSONObject().accumulate("status","No response available")
PidService pidService
对此:
RabbitMessagePublisher rabbitMessagePublisher
PidService pidService
static rabbitConfig = [ queue : "detran.transactions.191.requests" ]
JSONObject icomResp
def handleMessage(Map body, MessageContext messageContext) {
icomResp = new JSONObject().accumulate("status","No response available")
注意 pidService 现在是 class 属性,不是方法局部变量。如果 PidService 是 Grails 中的另一个服务,那么它应该可以正常注入并可用。至少这应该清除您的 NullPointerException,并让您继续调试。