首页 > 其他分享 >jpa多数据源时Hibernate配置自动生成表不生效

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

时间:2023-02-01 13:05:21浏览次数:41  
标签:Hibernate jpa 数据源 builder springframework orm import org


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自动生成表,和命名方式并没有生效。

原因我们可以看一下。

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

这里就是jpaProperties.getProperties()的地方,如果打断点可以看到,只有箭头这一个配置被加载进去了。上面的Hibernate的ddl和naming并没有进去。

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

来看一下HibernateProperties

jpa多数据源时Hibernate配置自动生成表不生效_jpa 动态数据源自动建表_03

这里才是真正让自动建表生效的地方,然而并没有加载进去。那么就需要我们手工来添加了。

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

这里面有个determineHibernateProperties方法,就是来组合jpaProperties和HibernateProperties的地方。我们应该使用这个方法来组合整个配置的map对象。

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

也就是在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());
}
}



标签:Hibernate,jpa,数据源,builder,springframework,orm,import,org
From: https://blog.51cto.com/u_13706148/6031389

相关文章

  • SpringBoot整合druid数据源
    SpringBoot默认使用HikariDataSource,但也可以整合外部DataSource。下面介绍SpringBoot_Druid整合整合有两种方式:1、starter整合 2、自定义整合1、starter整合2、自定......
  • Hibernate 自动进行数据封装
    1.前言Hibernate可以构建各种复杂的SQL语句,但其本质都是反射机制结合映射关系完成的。框架也仅是一款程序产品,人为编写的产物。要相信,只要你愿意,你完全可以实现自己的......
  • JNDI学习总结(三):tomcat下使用c3p0数据库连接池配置JNDI数据源
    tomcat是apache的,所以它的JNDI数据源默认使用commons组件的DBCP连接池来配置。如果想使用c3p0来配置数据源,就需要修改<Resource>标签里的部分配置选项,操作如下: 1.肯定......
  • 聊聊如何利用apollo与druid整合实现数据源动态热切
    前言本文的素材来源与某次和朋友技术交流,当时朋友就跟我吐槽说apollo不如nacos好用,而且他们还因为apollo发生过一次线上事故。故事的背景大概是如下前阵子朋友部门的数......
  • druid数据源配置//往上粘就完事了
    spring:datasource:type:com.alibaba.druid.pool.DruidDataSourcedriver-class-name:com.mysql.jdbc.Driverurl:jdbc:mysql://localhost:3306/test......
  • openlayers--添加数据源
    调用地图服务接口后,对接口返回值做处理--添加数据源if(res.features.length){//获取--根据行政区代码查询对应行政区的中心点letlons=res.features[0].properties.L......
  • 使用jpa非主键自增
    使用jpa非主键自增在使用jpa时,想要通过自增字段来更加直观自己插入多少数据需要的注解@GeneratedValue(strategy=GenerationType.AUTO)@Column(name="id",nulla......
  • [JPA错误]javax.persistence.EntityNotFoundException: Unable to find xxx
    解决方法:第一种:由于后来加上的实体、对象在之前的数据没有关联上,所以造成脏数据、故根本的解决方法,就是将之前的测试数据删除,重新添加数据就行了第二种:2.如果子表中......
  • springboot实现连接多个数据源
    dynamicdatasource导入依赖<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId>......
  • spring boot整合druid数据源
    druid源代码仓库地址:https://github.com/alibaba/druid一、通过配置类进行设置1、pom.xml中添加dependency<dependency><groupId>com.alibaba</groupId><arti......