为 Spring Boot 应用程序使用多个数据源配置时,未从属性转换器内的属性获取值

Posted

技术标签:

【中文标题】为 Spring Boot 应用程序使用多个数据源配置时,未从属性转换器内的属性获取值【英文标题】:Not getting value from property inside attributeconverter when using multiple datasource configuration for spring boot application 【发布时间】:2020-08-10 18:17:51 【问题描述】:

我通过参考下面的链接创建了具有多个数据源的 Spring Boot 应用程序: https://medium.com/@joeclever/using-multiple-datasources-with-spring-boot-and-spring-data-6430b00c02e7

并通过参考以下链接在实体级别添加加密: https://github.com/sunitk/generic-jpa-converter-encrypt-decrypt

使用多个数据源配置,我无法在属性转换器中获取属性值。它以 null 的形式出现。

但是使用单个数据源(默认属性)我可以获取属性值。

请告诉我如何使用多个数据源配置而不是默认的单个数据源属性来获取属性值?

【问题讨论】:

github 上的工作演示,你有什么问题? 【参考方案1】:

使用@Convert(converter = Xxx.class) 与特定数据源无关。您应该可以在每个@Entity 中使用转换器。

这是一个工作演示:multi-datasource-converter

它在多个数据源上使用您引用的转换器。

片段

application.properties

foo.datasource.jdbcUrl=jdbc:h2:mem:foo
foo.datasource.username=sa
foo.datasource.password=
foo.datasource.driver-class-name=org.h2.Driver

bar.datasource.jdbcUrl=jdbc:h2:mem:bar
bar.datasource.username=sa
bar.datasource.password=
bar.datasource.driver-class-name=org.h2.Driver

数据源的配置,选择一个作为@Primary 并将两个EntityManagerFactoryBuilders 指向正确的包

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "fooEntityManagerFactory",
        transactionManagerRef = "fooTransactionManager",
        basePackageClasses = FooRepository.class)
public class FooJpaConfiguration 

    @Primary
    @Bean(name = "fooDataSource")
    @ConfigurationProperties(prefix = "foo.datasource")
    public DataSource dataSource() 
        return DataSourceBuilder.create().build();
    

    @Primary
    @Bean(name = "fooEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            EntityManagerFactoryBuilder builder, @Qualifier("fooDataSource") DataSource dataSource) 
        return builder.dataSource(dataSource).packages("com.example.demo.foo").persistenceUnit("foo")....
....


@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "barEntityManagerFactory",
        transactionManagerRef = "barTransactionManager",
        basePackageClasses = BarRepository.class )
public class BarJpaConfiguration 

    @Bean(name = "barDataSource")
    @ConfigurationProperties(prefix = "bar.datasource")
    public DataSource dataSource() 
        return DataSourceBuilder.create().build();
    

    @Bean(name = "barEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean barEntityManagerFactory(
            EntityManagerFactoryBuilder builder, @Qualifier("barDataSource") DataSource dataSource) 
        return builder.dataSource(dataSource).packages("com.example.demo.bar").persistenceUnit("bar")

并在您的实体中使用转换器

package com.example.demo.foo;
...
@Entity
public class Foo 
    @Id
    private Long id;
    private String name;
    @Convert(converter = StringEncryptDecryptConverter.class)
    private String secret;

....
package com.example.demo.bar;
...
@Entity
public class Bar 
    @Id
    private Long id;
    private String name;
    @Convert(converter = StringEncryptDecryptConverter.class)
    private String secret;

【讨论】:

以上是关于为 Spring Boot 应用程序使用多个数据源配置时,未从属性转换器内的属性获取值的主要内容,如果未能解决你的问题,请参考以下文章

spring boot 中的多个 liquibase 配置

如何跨多个 Spring Boot 应用程序共享 H2 内存数据库?

使用spring-boot在多个数据库之间进行数据迁移

Spring Boot Spring Batch:没有 Spring 批处理元数据表的多个 DataSource

使用Spring Boot JPA配置多个数据源

Liquibase 与 Spring Boot 多个数据源,其中一个已禁用