手动创建 LocalContainerEntityManagerFactoryBean 时不考虑 HibernateProperties

时间:2021-02-08 12:00:13

标签: java spring-boot hibernate jpa spring-data-jpa

我正在尝试在现有的 Spring Boot 应用程序中设置多个数据库。

所以,我为每个数据库创建了一个这样的配置 bean:

@Configuration
@ComponentScan("com.example.user.data")
@EnableJpaRepositories(basePackages = "com.example.user.data.dao",
        entityManagerFactoryRef = "userEntityManagerFactory",
        transactionManagerRef = "userTransactionManager")
public class UserDataConfig {

    @Bean(name = "userDataSourceProps")
    @ConfigurationProperties("app.user.datasource")
    DataSourceProperties dataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean(name = "userDataSource")
    DataSource dataSource() {
        return dataSourceProperties().initializeDataSourceBuilder()
                .type(HikariDataSource.class)
                .build();
    }

    @Bean(name = "userEntityManagerFactory")
    LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder entityManagerFactoryBuilder) {
        return entityManagerFactoryBuilder
                .dataSource(dataSource())
                .packages("com.example.user.data.dao.entity")
                .persistenceUnit("users")
                .build();
    }

    @Bean(name = "userTransactionManager")
    PlatformTransactionManager transactionManager(@Qualifier("userEntityManagerFactory") LocalContainerEntityManagerFactoryBean entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory.getObject());
    }

}

并禁用这些自动配置:

  • DataSourceAutoConfiguration
  • DataSourceTransactionManagerAutoConfiguration

一切正常,但未应用 jpa/hibernate 属性;

例如,我有遵循命名约定的实体:SpringPhysicalNamingStrategy(默认情况下应使用);这些更改后,命名约定不起作用,即使我定义了属性:

spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy

我已经调试了 EntityManagerFactoryBuilder 创建,它的 jpaProperties 字段是空的!

我错过了什么吗?或者我应该在创建 LocalContainerEntityManagerFactoryBean 时手动传递 jpa-properties 和/或 hibernate-properties?例如:

return entityManagerFactoryBuilder
        .dataSource(dataSource())
        .properties(jpaAndHibernateProperties())
        .packages("com.example.user.data.dao.entity")
        .persistenceUnit("users")
        .build();

更新:

经过测试,我发现只有 HibernateProperties (spring.jpa.hibernate path) 没有应用。但是应用了 JpaProperties(spring.jpa 路径)。

1 个答案:

答案 0 :(得分:0)

基于org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration#entityManagerFactory,我们需要创建vendor-properties并将其传递给EntityManagerFactoryBuilder.properties:

return entityManagerFactoryBuilder
        .dataSource(dataSource())
        .properties(vendorProperties())
        .packages("com.example.user.data.dao.entity")
        .persistenceUnit(persistenceUnit)
        .build();

protected Map<String, Object> vendorProperties() {
    return new LinkedHashMap<>(this.hibernateProperties
            .determineHibernateProperties(jpaProperties.getProperties(),
                    new HibernateSettings()
                            .ddlAuto(() -> "none")
                            .hibernatePropertiesCustomizers(new ArrayList<>()))
    );
}