Dubbo远程rpc调用MybatisPlus自带的方法引发的几个错误

架构说明:

  先说下我们项目的大概架构,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点几的版本支持,但是我们的版本依赖不能修改,所以这里没有尝试,有兴趣的可以试试。

原文地址:https://www.cnblogs.com/timeout/p/15728847.html