使用来自 grails 4.0.3 中的 rabbit mq 消费者的数据在服务层的数据库中保存记录的问题
Posted
技术标签:
【中文标题】使用来自 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 【发布时间】:2021-12-17 23:28:29 【问题描述】:我在使用带有 Grails 4.0.3 的 RabbitMQ 队列时遇到了麻烦。和 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] cbrconsumer.AbstractConsumerContext:未处理的异常 java.lang.reflect.InvocationTargetException 在消费者 br.gov.cmb 的 RabbitMQ 消息处理程序中捕获。 pid.consumers.PidIssuingConsumer
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$5.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$2.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】:注意 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 现在是类属性,而不是方法局部变量。如果 PidService 是 Grails 中的另一个服务,那么它应该可以正常注入并且可以使用。至少这应该清除您的 NullPointerException,并让您继续进行调试。
【讨论】:
感谢您的评论。它现在工作正常。以上是关于使用来自 grails 4.0.3 中的 rabbit mq 消费者的数据在服务层的数据库中保存记录的问题的主要内容,如果未能解决你的问题,请参考以下文章