Dubbo遠程rpc調用Mybatis-Plus自帶的方法引發的幾個錯誤

架構說明:

  先說下我們項目的大概架構,nacos用作配置和服務註冊發現中心。其他微服務在nacos註冊,通過Dubbo進行遠程調用。

  提前說明,爲了方便,我這裏講調用者=消費者,提供者=生產者。

  我這裏的消費者,沒有其他過多的包類,可以簡單理解,只有一個包,包裏每個類,對應一個數據庫表的維護,操作都是調用生產者提供的服務接口。

出現的錯誤一:

這段代碼是在消費這裏面寫的,需要遠程調用scpIcpbussService的list接口

LambdaQueryWrapper<Icpbuss> wrapper = new LambdaQueryWrapper<>();
            wrapper.select(Icpbuss::getId).eq(Icpbuss::getSOrgCode, item.getSOrgCode())
                    .eq(Icpbuss::getSupplierSystem, item.getSupplierSystem())
                    .eq(Icpbuss::getROrgCode, item.getROrgCode())
                    .eq(Icpbuss::getRequirementSystem, item.getRequirementSystem());
            List<Icpbuss> dataList = IcpbussService.list(wrapper);

  運行後,就會報錯,如下

com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: can not find lambda cache for this entity [com.xxx.xxx.basic.entity.xxxIcpbuss]
com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: can not find lambda cache for this entity [com.xxx.xxx.basic.entity.xxxIcpbuss]
	at com.baomidou.mybatisplus.core.toolkit.ExceptionUtils.mpe(ExceptionUtils.java:49)
	at com.baomidou.mybatisplus.core.toolkit.Assert.isTrue(Assert.java:38)
	at com.baomidou.mybatisplus.core.toolkit.Assert.notNull(Assert.java:72)
	at com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper.tryInitCache(AbstractLambdaWrapper.java:89)
	at com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper.getColumnCache(AbstractLambdaWrapper.java:78)
	at com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper.columnToString(AbstractLambdaWrapper.java:62)
	at com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper.lambda$columnsToString$0(AbstractLambdaWrapper.java:53)
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
	at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
	at com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper.columnsToString(AbstractLambdaWrapper.java:53)
	at com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper.select(LambdaQueryWrapper.java:84)
	at com.xxx.xxx.xxx.spi.IcpbussConsumerStrategySpi.lambda$saveData$2(IcpbussConsumerStrategySpi.java:100)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at com.xxx.xxx.xxx.spi.IcpbussConsumerStrategySpi.saveData(IcpbussConsumerStrategySpi.java:98)
	at com.xxx.xxx.xxx.spi.IcpbussConsumerStrategySpi.receive(IcpbussConsumerStrategySpi.java:82)
	at com.xxx.xxx.xxx.spi.IcpbussConsumerStrategySpi.receive(IcpbussConsumerStrategySpi.java:55)
	at com.xxx.xxx.xxx.spi.IcpbussConsumerStrategySpi$$FastClassBySpringCGLIB$$f3488070.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
	at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89)
	at com.xxx.xxx.xxx.aspect.xxxAspect.doAroundAdvice(xxxAspect.java:54)
	at com.xxx.xxx.xxx.aspect.xxxAspect$$FastClassBySpringCGLIB$$8e07f5f5.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
	at com.xxx.xxx.xxx.aspect.xxxAspect$$EnhancerBySpringCGLIB$$ddfaddf9.doAroundAdvice(<generated>)
	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.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624)
	at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698)
	at com.xxx.xxx.xxx.spi.IcpbussConsumerStrategySpi$$EnhancerBySpringCGLIB$$7d4ce1e5.receive(<generated>)
	at com.xxx.xxx.spi.dispatcher.support.DefaultDataOutSpi.receiveProcessor(DefaultDataOutSpi.java:98)
	at com.xxx.xxx.spi.dispatcher.support.DefaultDataOutSpi.lambda$null$1(DefaultDataOutSpi.java:63)
	at org.apache.camel.support.processor.DelegateSyncProcessor.process(DelegateSyncProcessor.java:65)
	at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$RedeliveryTask.doRun(RedeliveryErrorHandler.java:810)
	at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$RedeliveryTask.run(RedeliveryErrorHandler.java:718)
	at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:187)
	at org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:64)
	at org.apache.camel.processor.Pipeline.process(Pipeline.java:184)
	at org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:398)
	at org.apache.camel.impl.engine.DefaultAsyncProcessorAwaitManager.process(DefaultAsyncProcessorAwaitManager.java:83)
	at org.apache.camel.support.AsyncProcessorSupport.process(AsyncProcessorSupport.java:41)
	at org.apache.camel.component.rabbitmq.RabbitConsumer.doHandleDelivery(RabbitConsumer.java:109)
	at org.apache.camel.component.rabbitmq.RabbitConsumer.handleDelivery(RabbitConsumer.java:84)
	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)

  原因以及解決方法:百度以及自己嘗試,發現Dubbo遠程調用不支持LambdaQueryWrapper或者QueryWrapper等類型的傳遞。儘量改用傳遞實體等,需要構建查詢條件的,還是在提供者的實現類裏面去使用LambdaQueryWrapper或者QueryWrapper等;還有說法是Mybatis-Plus的版本太低,但是我這裏沒有嘗試。

如果上面的錯誤你改了,可以正常運行了,那就不用看下面的錯誤二了。

錯誤二:

  當我改了錯誤一以後,又出現了這個錯誤,如下:

  百度到的,都是說沒有配置主數據,之類的,但是我去了服務的提供者看配置,是配置的,可以正常使用。這裏說明下,我服務的消費着是不需要數據庫連接的,全程都是通過Dubbo調用遠程服務。

  出現錯誤代碼是:service.saveBatch(dataList); 說明:saveBatch是Mybatis-Plus中Service自帶的方法。

org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is com.baomidou.dynamic.datasource.exception.CannotFindDataSourceException: dynamic-datasource can not find primary datasource
    at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:309)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.startTransaction(AbstractPlatformTransactionManager.java:400)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:595)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:382)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698)
    at org.apache.dubbo.common.bytecode.proxy2$$EnhancerBySpringCGLIB$$e170fea3.saveBatch(<generated>)
    at com.xxx.xxx.xxx.spi.IcpbussConsumerStrategySpi.saveData(IcpbussConsumerStrategySpi.java:98)
    at com.xxx.xxx.xxx.spi.IcpbussConsumerStrategySpi.receive(IcpbussConsumerStrategySpi.java:82)
    at com.xxx.xxx.xxx.spi.IcpbussConsumerStrategySpi.receive(IcpbussConsumerStrategySpi.java:55)
    at com.xxx.xxx.xxx.spi.IcpbussConsumerStrategySpi$$FastClassBySpringCGLIB$$f3488070.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
    at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89)
    at com.xxx.xxx.xxx.aspect.xxxAspect.doAroundAdvice(xxxAspect.java:54)
    at com.xxx.xxx.xxx.aspect.xxxAspect$$FastClassBySpringCGLIB$$8e07f5f5.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
    at com.xxx.xxx.xxx.aspect.xxxAspect$$EnhancerBySpringCGLIB$$f7832c33.doAroundAdvice(<generated>)
    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.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624)
    at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698)
    at com.xxx.xxx.xxx.spi.IcpbussConsumerStrategySpi$$EnhancerBySpringCGLIB$$dc9a1d21.receive(<generated>)
    at com.xxx.xxx.spi.dispatcher.support.DefaultDataOutSpi.receiveProcessor(DefaultDataOutSpi.java:98)
    at com.xxx.xxx.spi.dispatcher.support.DefaultDataOutSpi.lambda$null$1(DefaultDataOutSpi.java:63)
    at org.apache.camel.support.processor.DelegateSyncProcessor.process(DelegateSyncProcessor.java:65)
    at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$RedeliveryTask.doRun(RedeliveryErrorHandler.java:810)
    at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$RedeliveryTask.run(RedeliveryErrorHandler.java:718)
    at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:187)
    at org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:64)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:184)
    at org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:398)
    at org.apache.camel.impl.engine.DefaultAsyncProcessorAwaitManager.process(DefaultAsyncProcessorAwaitManager.java:83)
    at org.apache.camel.support.AsyncProcessorSupport.process(AsyncProcessorSupport.java:41)
    at org.apache.camel.component.rabbitmq.RabbitConsumer.doHandleDelivery(RabbitConsumer.java:109)
    at org.apache.camel.component.rabbitmq.RabbitConsumer.handleDelivery(RabbitConsumer.java:84)
    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: com.baomidou.dynamic.datasource.exception.CannotFindDataSourceException: dynamic-datasource can not find primary datasource
    at com.baomidou.dynamic.datasource.DynamicRoutingDataSource.determinePrimaryDataSource(DynamicRoutingDataSource.java:90)
    at com.baomidou.dynamic.datasource.DynamicRoutingDataSource.getDataSource(DynamicRoutingDataSource.java:141)
    at com.baomidou.dynamic.datasource.DynamicRoutingDataSource.determineDataSource(DynamicRoutingDataSource.java:77)
    at com.baomidou.dynamic.datasource.ds.AbstractRoutingDataSource.getConnection(AbstractRoutingDataSource.java:43)
    at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:265)
    ... 55 more

  原因以及解決方法:初步判斷的原因是如果消費者,調用的是提供者服務的Mybatis-Plus自帶的底層方法,比如list,save等方法時候,就會出現上面的錯誤。解決辦法是在你的接口層重新封裝一下。

Mybatis-Plus自帶的方法部分。

 

封裝如下:

 

// 接口層
public interface IXxxService extends IService<ScpIcpbuss> {
    /**
     * 保存數據
     * 
     */
    public void saveNew(XXX xxx);
}


// 實現層
@Service
@DubboService(version = "1.0.0")
public class XxxServiceImpl extends ServiceImpl<xxxMapper, xxx> implements IXxxService {

    @Override
    public void saveNew(XXX xxx) {
        this.save(xxx);
    }

}

 

  代碼調用說明:

@Slf4j
@Service
public class IcpbussConsumerStrategySpi{

    @DubboReference(version = "1.0.0")
    private IXxxService service;

    // 保存數據
    private void saveData(XXX xxx) {
        // 這樣調用會報錯,調用的是Mybatis-plus的方法
        service.save(xxx);
        // 這樣正確,不會出現多數據源未配置主數據源的錯誤,調用的是我們自己封裝的saveNew方法
        service.saveNew(xxx);
    }
}
    

  最後:

  目前只是一種簡單的解決方法,因爲項目比較急,沒有深入研究,僅供參考,提供一種思路,如有錯漏或者有大佬知道原因的可以留言指教。

  百度到的說Mybatis-Plus不支持Dubbo遠程調用使用LambdaQueryWrapper之類的傳參,但是也有說3點幾的版本支持,但是我們的版本依賴不能修改,所以這裏沒有嘗試,有興趣的可以試試。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章