如何在 Spring Data JPA 上配置数据库,其中其凭据映射到另一个实体(在其他数据库上)?

问题描述 投票:0回答:1

用例

我有一些客户,每个客户都运行自己的后端实例,该实例连接到自己的数据库,每个后端实例都有自己的数据库,但用于连接到这些数据库的凭据(主数据库)都是相同的,并且这些凭据是在另一个数据库中,无论后端实例如何,我的观点是在 Spring Data Jpa 上配置一个数据库连接,其凭据依赖于另一个数据库(它们存在于该数据库的映射实体上),然后我创建了一个包含数据库凭据的

Entity
(和其他信息):

@Data
public class Assinante {
    @Id
    @Column(name="cnpj_da_base")
    private String cnpj;
    @Column(name="db_jdbc_url")
    private String databaseURL;
    @Column(name="db_user")
    private String databaseUser;
    @Column(name="db_password")
    private String databasePassword;
    @Enumerated(EnumType.STRING)
    private Categoria classificacao;
    @Column(name="token_varejo")
    private String tokenVarejo;
    @Column(name="api_url")
    private String apiUrl;
    @Column(name="proxy_url")
    private String proxyUrl;
    @Column(name="proxy_https_port")
    private Integer proxyHttpsPort;
    @Column(name="proxy_login")
    private String proxyLogin;
    @Column(name="proxy_pass")
    private String proxyPass;
    @Column(name="valido_ate")
    private LocalDate validoAte;
}

我需要一种方法来根据该实体中的凭据设置主数据库源,然后我这样做了:

对于主数据库:

@Configuration
@EnableJpaRepositories(
        basePackages = "org.crm", // Adjusted package for primary repositories
        entityManagerFactoryRef = "mainEntityManagerFactory",
        transactionManagerRef = "mainTransactionManager",
        excludeFilters = @ComponentScan.Filter(
                type = FilterType.ASSIGNABLE_TYPE, classes = {
                AssinanteRepository.class
        }
        )
)
public class DataSourceConfig {

    @Value("{app.assinante-cnpj}")
    private String cnpj;

    @Autowired
    private EntityManager entityManager;

    private HikariConfig hikariConfig;

    @PostConstruct
    public void init() {
        SimpleJpaRepository assinanteRepository = new SimpleJpaRepository<Assinante, String>(Assinante.class, entityManager);
        Optional<Assinante> assinante = assinanteRepository.findById(cnpj);
        if (assinante.isEmpty()) {
            throw new RuntimeException("CNPJ NÃO ASSINADO");
        }
        // Configurações do Hikari baseadas no assinante
        hikariConfig.setJdbcUrl(assinante.get().getDatabaseURL());
        hikariConfig.setUsername(assinante.get().getDatabaseUser());
        hikariConfig.setPassword(assinante.get().getDatabasePassword());

        // Supondo que você tenha outras propriedades no objeto Assinante
        hikariConfig.setConnectionTestQuery("SELECT 1");
        hikariConfig.setValidationTimeout(3000);
        hikariConfig.setIdleTimeout(60000);
        hikariConfig.setMaxLifetime(1800000);
        hikariConfig.setMinimumIdle(5);
        hikariConfig.setMaximumPoolSize(20);
    }

    @Bean
    @Primary
    public DataSource dataSource() throws Exception {
        return new HikariDataSource(hikariConfig);
    }

    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean mainEntityManagerFactory() throws Exception {
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setDataSource(dataSource());
        factory.setPackagesToScan("org.crm"); // Main packages to scan
        factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        Properties properties = new Properties();
        properties.put("hibernate.physical_naming_strategy", "org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy");
        properties.put("hibernate.implicit_naming_strategy", "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
        factory.setJpaProperties(properties);
        return factory;
    }

    @Bean
    @Primary
    public JpaTransactionManager mainTransactionManager(EntityManagerFactory mainEntityManagerFactory) {
        return new JpaTransactionManager(mainEntityManagerFactory);
    }
}

对于包含凭据的数据库:

@Configuration
@EnableJpaRepositories(
        basePackages = "org.crm.domain.entidadesBusiness.assinantesSistema", // Pacote onde está o repositório do Assinante
        entityManagerFactoryRef = "assinanteEntityManagerFactory",
        transactionManagerRef = "assinanteTransactionManager"
)
public class AssinanteDataSourceConfig {

    @Bean
    public DataSource assinanteDataSource() {
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setJdbcUrl("secret");
        hikariConfig.setUsername("secret");
        hikariConfig.setPassword("secret");

        // Configurações do HikariCP
        hikariConfig.setConnectionTestQuery("SELECT 1");
        hikariConfig.setValidationTimeout(3000);
        hikariConfig.setIdleTimeout(60000);
        hikariConfig.setMaxLifetime(1800000);
        hikariConfig.setMinimumIdle(5);
        hikariConfig.setMaximumPoolSize(20);

        return new HikariDataSource(hikariConfig);
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean assinanteEntityManagerFactory() {
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setDataSource(assinanteDataSource());
        factory.setPackagesToScan(Assinante.class.getPackageName());
        factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        Properties properties = new Properties();
        properties.put("hibernate.physical_naming_strategy", "org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy");
        properties.put("hibernate.implicit_naming_strategy", "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
        factory.setJpaProperties(properties);
        return factory;
    }

    @Bean
    public JpaTransactionManager assinanteTransactionManager(EntityManagerFactory assinanteEntityManagerFactory) {
        return new JpaTransactionManager(assinanteEntityManagerFactory);
    }
}


问题是当我运行应用程序时,我在

EntityManager 
DataSource

之间出现了循环依赖
spring-boot
1个回答
0
投票

我通过将注释

@Primary
移动到包含凭据的数据库并使用

解决了这个问题
@Autowired
private EntityManagerFactory entityManagerFactory;

    EntityManager entityManager = entityManagerFactory.createEntityManager();

相反

@Autowired
private EntityManager entityManager;
© www.soinside.com 2019 - 2024. All rights reserved.