jpa多数据源时Hibernate配置自动生成表不生效的解决
作者:天涯泪小武 发布时间:2023-04-24 06:19:55
标签:jpa,多数据源,Hibernate,生成表
jpa配置多数据源教程很多,在Springboot2之后有一些变化,来看一下。
application.yml如下
spring:
application:
name: t3cc
datasource:
primary:
jdbc-url: jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/${DB_NAME:anbang}?useUnicode=true&characterEncoding=UTF8&serverTimezone=Hongkong
username: root
password: root
secondary:
jdbc-url: jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/${DB_NAME:anbang1}?useUnicode=true&characterEncoding=UTF8&serverTimezone=Hongkong
username: root
password: root
jpa:
database: mysql
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect #不加这句则默认为myisam引擎
hibernate:
ddl-auto: update
naming:
physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
open-in-view: true
properties:
enable_lazy_load_no_trans: true
show-sql: true
cloud:
nacos:
discovery:
server-addr: ${NACOS_SERVER:localhost:8848}
###############################---log---##############################
logging:
file: ./logback.log
yml里配置了两个数据源,和一些jpa和Hibernate的配置。
下面是DataSource的配置
/**
* @author wuweifeng wrote on 2019/3/5.
*/
@Configuration
public class DataSourceConfig {
@Primary
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource dataSourceOrder() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource dataSourceAuth() {
return DataSourceBuilder.create().build();
}
}
下面是第一个数据源的配置
package com.mm.dmp.t3cc.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
/**
* @author wuweifeng wrote on 2019/3/5.
*/
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryPrimary",
transactionManagerRef = "transactionManagerPrimary",
basePackages = {"com.mm.dmp.t3cc.core.repository.one"})
public class OneConfig {
@Resource
@Qualifier("primaryDataSource")
private DataSource primaryDataSource;
@Primary
@Bean(name = "entityManagerPrimary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
@Resource
private JpaProperties jpaProperties;
@Resource
private HibernateProperties properties;
/**
* 设置实体类所在位置
*/
@Primary
@Bean(name = "entityManagerFactoryPrimary")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean entityManagerFactory = builder
.dataSource(primaryDataSource)
//.packages(classes)
//设置实体类所在位置
.packages("com.mm.dmp.t3cc.core.entity.one")
.persistenceUnit("primaryPersistenceUnit")
//.properties(jpaProperties.getProperties())
.properties(properties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings()))
.build();
return entityManagerFactory;
}
@Primary
@Bean(name = "transactionManagerPrimary")
public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
这里会和别人的配置不一样,主要区别在于HibernateProperties。别人的在第61行,我注释掉的那行,会直接使用jpaProperties.getProperties()。当你这样写之后,会发现yml里配置的Hibernate的update自动生成表,和命名方式并没有生效。
原因我们可以看一下。
这里就是jpaProperties.getProperties()的地方,如果打断点可以看到,只有箭头这一个配置被加载进去了。上面的Hibernate的ddl和naming并没有进去。
来看一下HibernateProperties
这里才是真正让自动建表生效的地方,然而并没有加载进去。那么就需要我们手工来添加了。
这里面有个determineHibernateProperties方法,就是来组合jpaProperties和HibernateProperties的地方。我们应该使用这个方法来组合整个配置的map对象。
也就是在OneConfig类中,把两个Properties都定义出来,然后组合一下,就是箭头的地方。在debug时,就可以看到Hibernate的配置也都加载进来了。
OK,以上就是动态数据源配置Hibernate自动建表不生效的原因。
下面是第二个数据源的配置
package com.mm.dmp.t3cc.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
/**
* @author wuweifeng wrote on 2019/3/5.
*/
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactorySecondary",
transactionManagerRef = "transactionManagerSecondary",
basePackages = {"com.mm.dmp.t3cc.core.repository.two"}) //设置Repository所在位置
public class TwoConfig {
@Resource
@Qualifier("secondaryDataSource")
private DataSource secondaryDataSource;
@Resource
private JpaProperties jpaProperties;
@Resource
private HibernateProperties properties;
@Bean(name = "entityManagerSecondary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactorySecondary(builder).getObject().createEntityManager();
}
@Bean(name = "entityManagerFactorySecondary")
public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary(EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean entityManagerFactory
= builder
.dataSource(secondaryDataSource)
//.packages(classes)
//设置实体类所在位置
.packages("com.mm.dmp.t3cc.core.entity.two")
.persistenceUnit("secondaryPersistenceUnit")
.properties(properties.determineHibernateProperties(jpaProperties.getProperties(), new
HibernateSettings()))
.build();
return entityManagerFactory;
}
@Bean(name = "transactionManagerSecondary")
public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
}
}
如果你觉得这样比较麻烦,并且还有分库分表的需求,那么可以使用sharding jdbc来操作,移步这一篇文章
来源:https://tianyalei.blog.csdn.net/article/details/96977099


猜你喜欢
- 新手练手必备~密码账户为:先创建账户类:package cn.Atm;/*** @author 偶my耶*/import java.io.*
- 本篇内容主要讲述了实现基于微软账户的第三方身份验证、实现双因子身份验证、 验证码机制这3个内容。实现基于微软账户的第三方身份验证在
- 当我们打开app的时候是不是会有一瞬间的白屏然后再进入主活动,虽然这并不会造成什么不好的后果,但是感觉用户体验就不是很好。像网易云音乐等等
- static和const是C++程序设计中非常重要的概念,本文实例列举了C++类中的static和const的规则和用法。供大家参考借鉴。具
- 前言:如何在C++代码中调用写好的C接口?你可能会奇怪,C++不是兼容C吗?直接调用不就可以了,那么我们来测试一下,先看看C++如何调用C代
- 一、前言在Java编码中,我们经常会遇到List与数组的转换,包括对象List与对象数组的转换,以及对象List与基本数据类型数组的转换,下
- 1 数据响应  数据响应一般分为两种:页面响应和数据响应,一般来说页面响应是用来开发一些单体项目(也就是
- 前言Gradle,这是一个基于 JVM 的富有突破性构建工具。Gradle 正迅速成为许多开源项目和前沿企业构建系统的选择,同时也在挑战遗留
- 最近研究OpenCV想用java进行开发,因此研究了一下怎么在Eclipse中配置基于java的Opencv.第一步:先到OpenCV官网下
- 实例如下:public class DataTypeChangeHelper { /** * 将一个单字节的b
- 一、SpringMVC使用1.工程创建创建maven工程。添加java、resources目录。引入Spring-webmvc 依赖。<
- 本文实例讲述了C#发送数据到剪贴板及从剪贴板中取数据的方法。分享给大家供大家参考。具体如下:1. 发送数据到剪贴板using System.
- 废话不多说了,先给大家上左右无限滑动的代码了。1.左右无限滑动public class MainActivity extends AppCo
- Map接口简介Map接口是一种双列集合,它的每个元素都包含一个键对象Key和值对象Value,键和值对象之间存在一种对应关系,称为映射。从M
- 简介Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩
- 前言:在 Java 中,让线程休眠的方法有很多,这些方法大致可以分为两类,一类是设置时间,在一段时间后自动唤醒,而另一个类是提供了一对休眠和
- 接着上一篇进行学习java文件上传下载1。五、断点续传 对于熟用QQ的程序员,QQ的断点续传功能应该是印象很深刻的。因为它很实用也
- 本文使用的Unicode+DLL+Debug的方式,因为不想最后生成的exe文件太大。环境搭建步骤如下:1、下载wxWidgets包:登录w
- 一、数组创建1.1 声明并赋值int[] a = {1,2,3};1.2 声明数组名开辟空间并且赋值int[] a;a = new int[
- 阅读提示 具有mybatis基础,熟练使用mybatis-plus。概述 我们都知道,mybatis-plus是一个mybatis的增强