jpa多数据源时Hibernate配置自动生成表不生效的解决

网友投稿 1410 2022-10-27

jpa多数据源时Hibernate配置自动生成表不生效的解决

jpa多数据源时Hibernate配置自动生成表不生效的解决

目录application.yml如下下面是DataSource的配置下面是第一个数据源的配置下面是第二个数据源的配置

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.EnableJpaRepositorhttp://ies;

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 PlatformTransactionManhttp://ager 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 = "transactionManagerSecondaffEnEry")

public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {

return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());

}

}

如果你觉得这样比较麻烦,并且还有分库分表的需求,那么可以使用sharding jdbc来操作,移步这一篇文章

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:独立站小程序化,中国品牌出海面临的挑战
下一篇:小程序跳转APP的优势,为什么线上教育服务最佳方式是小程序化?
相关文章

 发表评论

暂时没有评论,来抢沙发吧~