jpa多數(shù)據(jù)源時Hibernate配置自動生成表不生效的解決
jpa配置多數(shù)據(jù)源教程很多,在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 #不加這句則默認(rèn)為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.logyml里配置了兩個數(shù)據(jù)源,和一些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();
}
}下面是第一個數(shù)據(jù)源的配置
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;
/**
* 設(shè)置實體類所在位置
*/
@Primary
@Bean(name = "entityManagerFactoryPrimary")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean entityManagerFactory = builder
.dataSource(primaryDataSource)
//.packages(classes)
//設(shè)置實體類所在位置
.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());
}
}這里會和別人的配置不一樣,主要區(qū)別在于HibernateProperties。別人的在第61行,我注釋掉的那行,會直接使用jpaProperties.getProperties()。當(dāng)你這樣寫之后,會發(fā)現(xiàn)yml里配置的Hibernate的update自動生成表,和命名方式并沒有生效。
原因我們可以看一下。

這里就是jpaProperties.getProperties()的地方,如果打斷點可以看到,只有箭頭這一個配置被加載進(jìn)去了。上面的Hibernate的ddl和naming并沒有進(jìn)去。

來看一下HibernateProperties

這里才是真正讓自動建表生效的地方,然而并沒有加載進(jìn)去。那么就需要我們手工來添加了。

這里面有個determineHibernateProperties方法,就是來組合jpaProperties和HibernateProperties的地方。我們應(yīng)該使用這個方法來組合整個配置的map對象。

也就是在OneConfig類中,把兩個Properties都定義出來,然后組合一下,就是箭頭的地方。在debug時,就可以看到Hibernate的配置也都加載進(jìn)來了。
OK,以上就是動態(tài)數(shù)據(jù)源配置Hibernate自動建表不生效的原因。
下面是第二個數(shù)據(jù)源的配置
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"}) //設(shè)置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)
//設(shè)置實體類所在位置
.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來操作,移步這一篇文章
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java后臺本地文件轉(zhuǎn)為MultipartFile類型的實現(xiàn)方式
在Java后臺將本地文件轉(zhuǎn)換為MultipartFile類型,可以通過使用FileItemFactory創(chuàng)建FileItem,然后使用CommonsMultipartFile類構(gòu)造一個MultipartFile對象,將本地文件流轉(zhuǎn)換為MultipartFile,getMultipartFiles()和getMultipartFiles()方法2025-02-02
簡單了解Java synchronized關(guān)鍵字同步
這篇文章主要介紹了簡單了解Java synchronized關(guān)鍵字同步,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-09-09
Java concurrency線程池之線程池原理(二)_動力節(jié)點Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了Java concurrency線程池之線程池原理第二篇,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06
解決Java的InputMismatchException異常
這篇文章介紹了解決Java的InputMismatchException異常的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-12-12
windows下vscode+vs2019開發(fā)JNI的示例
本文給大家普及windows下vscode+vs2019開發(fā)JNI的示例以及各個環(huán)節(jié)的注意事項,文章通過示例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-06-06

