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

问题描述

我通过参考以下链接创建了具有多个数据源的 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

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

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

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

标签: spring-bootencryptionspring-data-jpa

解决方案


使用 a@Convert(converter = Xxx.class)与特定的数据源无关。您应该能够在每个@Entity.

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

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

片段

应用程序属性

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;

推荐阅读