Springboot Jpa 有关多数据源的问题

 

心路历程

  • 百度:“Spring boot Jpa 多数据源”

        参考博文:https://www.cnblogs.com/fernfei/p/12119601.html

  我根据以上博文进行了一系列的配置,我整个项目也都运行不起来了,第一天过去了。

java.sql.SQLException: net.sf.log4jdbc.DriverSpy
	at com.alibaba.druid.util.JdbcUtils.createDriver(JdbcUtils.java:653)
	at com.alibaba.druid.pool.DruidDataSource.resolveDriver(DruidDataSource.java:1212)
	at com.alibaba.druid.pool.DruidDataSource.init(DruidDataSource.java:887)
	at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1383)
	at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1379)
	at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:109)
	at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:151)
	at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:115)
	at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:78)

  对这个错误进行百度,基本上都是有关丢包的错误,需要加入什么的jar类似这样的,实际解决方法如下。因为在application.yml里面有相关配置,我也不知道这个问题的解决方向。(同事帮忙解决)

 

  • 解决了上述问题之后,项目还是没有成功运行起来,具体的错误已经不记得了。然后同事推荐一个博文“动态切换数据库”,第二天过去了

  参考博文:https://blog.csdn.net/shentan0000/article/details/116274449

 

  • 我根据上述博文的操作,我成功了,可以在前端对两个不同数据库的api请求都成功的获取数据了。接着就遇到致命的问题是,在一个会话中(方法中)同时做两个库的操作,就会直接报异常。第三天过去了

  报错提示:对象 名“表名”无效。这里并不是真的不存在这个表,而是连接的数据源不对,所以导致了找不到对应表。

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: 对象名 'so_xxx' 无效。

   针对动态切换数据源的操作,在一个方法里面同时更新两个数据源数据的操作,至今没得到解决。

 

  • 我就想啊想,我也想不通为什么。这大概是我得出来的结论。第四天

 

  • 那么根据得出来的结论,要么同时两个数据库连接存在,要么切断连接建立新的连接。最终选择了回到最初的配置方式。

  参考博文:https://blog.csdn.net/taojin12/article/details/88573580

  毕竟我们是要以解决同时操作两个数据库问题为目标,所以没对动态切换数据源做更深的研究。(但其实我是很有兴趣弄明白他是为什么不能实现的)

 

  • 配置完后遇到的第一个问题
Application failed to start due to an exception

org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'PxxMainRepository' defined in null: Cannot register bean definition [Root bean: class [org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] for bean 'POMainRepository': There is already [Root bean: class [org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] bound.
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:894)
	at org.springframework.data.repository.config.RepositoryConfigurationDelegate.registerRepositoriesIn(RepositoryConfigurationDelegate.java:173)
	at org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport.registerBeanDefinitions(RepositoryBeanDefinitionRegistrarSupport.java:85)

  凭直觉解决,我的primary数据库配置package为“com.vxx”,数据源二的package配置为“com.vxx.uxx”,我想还是因为我把数据源二的包裹在默认数据源的包下,所以导致有些类不知道该选择哪个数据源了。所以我就把uxx移动到了com层,于是数据源二的package配置为“com.uxx”,这样两个就不会相互干扰了。

  实际上package可以进行多包配置,写的更细一些把com.vxx下的所有列出来也是可以的。如下

basePackages = {"com.vxx.axx","com.vxx.bxx"}

builder.dataSource(fosunDS).properties(vendorProperties)
       .packages("com.vxx.axx","com.vxx.bxx")

 

  • 配置完遇到的第二个问题
[Vertex-SRM:0.0.0.0:8809] 20:24:33.681 DEBUG 17684 [main] o.s.b.d.LoggingFailureAnalysisReporter Application failed to start due to an exception

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.xx.service.PxxMainService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1646)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1205)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1166)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:855)

  我百度了,参看博文:https://www.codetd.com/article/6188038

  里面有个 component-scan  的配置,这里刚好项目中有个被注释了的 @ComponentScan AppRun 这个类上(不然我可能不知道把这个配置加在哪),所以我就重新加上了

@ComponentScan(basePackages = {"com.vxx","com.uxx"})
public class AppRun {

    public static void main(String[] args) {
        SpringApplication.run(AppRun.class, args);
    }

 

  • 项目成功的运行起来,这时候又遇到了一个问题,在有些查询时候报错,列名 “createTime”无效

   正常我们是需要在字段上添加注解 @Column(name = "create_time") ,但系统有人默认配置可以将驼峰式映射成_小写的形式,即 createTime 对应 create_time

这个默认的配置到底在哪呢?遇到这个问题的时候,描述都不好描述,自然没搜到答案。但实际上,有关这个默认配置的处理,在上述博文中又出现过(动态配置数据源博文),同事提醒了我,我需要反思自己,我其实没有认真看这些添加东西。

Map<String, String> properties = jpaProperties.getProperties();
//要设置这个属性,实现 CamelCase -> UnderScore 的转换
properties.put("hibernate.physical_naming_strategy",
                "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");

 

  至此,项目运行成功,两个数据库的操作也完美执行。

 

 

posted @ 2021-12-23 21:15  茄子鱼  阅读(608)  评论(0编辑  收藏  举报