Spring Data JPA - 多个EnableJpaRepositories

时间:2017-08-13 17:27:34

标签: spring hibernate jpa spring-data-jpa datasource

我的应用程序有多个数据源,因此我根据此URL创建了两个数据源配置类。

但是在运行spring boot应用程序时遇到错误

  

描述:   com.cavion.services.UserDataService中的字段userDataRepo需要一个名为' entityManagerFactory'的bean。无法找到。   行动:   考虑定义一个名为' entityManagerFactory'在你的配置中。

通过StackOverflow上的这个Question帮助我找出问题。我需要在我的JPA存储库中指定entityManagerFactoryRef。

但我有很多存储库类,其中一些使用Entitymanager' A'其中一些人使用' B' 。我当前的spring boot应用程序类就像这样

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
    DataSourceTransactionManagerAutoConfiguration.class })
@EnableTransactionManagement
@EntityScan("com.info.entity")
@ComponentScan({"com.info.services","com.info.restcontroller"})
@EnableJpaRepositories("com.info.repositories")
public class CavionApplication {

public static void main(String[] args) {
    SpringApplication.run(CavionApplication.class, args);
}
@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
    return args -> {

        System.out.println("Let's inspect the beans provided by Spring Boot:");

        String[] beanNames = ctx.getBeanDefinitionNames();
        Arrays.sort(beanNames);
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }

    };
}}

我已经在spring引导类上给出了EnableJpaRepositories,那么如何配置多个EnableJpaRepositories以便我可以配置多个entityManagerFactory?

请建议设置多个数据源的最佳方法。

3 个答案:

答案 0 :(得分:24)

为了让spring知道Repository@EnableJpaRepositories相关的内容,您应该在Servers注释中定义它。让我们假设我们有两个实体,Domains实体和Domains实体,每个实体都有自己的Repo,然后每个Repository都有自己的JpaDataSource配置。

<强> 1。根据与之相关的数据源对所有存储库进行分组。例如

org.springdemo.multiple.datasources.repository.domains个实体的存储库(包:package org.springdemo.multiple.datasources.repository.domains; import org.springdemo.multiple.datasources.domain.domains.Domains; import org.springframework.data.jpa.repository.JpaRepository; public interface DomainsRepository extends JpaRepository<Domains,Long> { } ):

Servers

org.springdemo.multiple.datasources.repository.servers个实体的存储库(包:package org.springdemo.multiple.datasources.repository.servers; import org.springdemo.multiple.datasources.domain.servers.Servers; import org.springframework.data.jpa.repository.JpaRepository; public interface ServersRepository extends JpaRepository<Servers,Long> { }

Domains

<强> 2。对于每个JPA Data Soruce,您需要定义配置,在此示例中,我将展示如何配置两个不同的DataSource

basePackages Jpa配置:数据源与存储库之间的关系在@Configuration @EnableJpaRepositories( entityManagerFactoryRef = "domainsEntityManager", transactionManagerRef = "domainsTransactionManager", basePackages = {"org.springdemo.multiple.datasources.repository.domains"} ) public class DomainsConfig { 值中定义,这就是为什么需要根据实体管理器将存储库分组到不同的包中的原因每个回购都会使用。

Servers

Servers数据源配置:如您所见,basePackages值的包名称为entityManagerFactoryRef存储库,transactionManagerRef@Configuration @EnableJpaRepositories( entityManagerFactoryRef = "serversEntityManager", transactionManagerRef = "serversTransactionManager", basePackages = {"org.springdemo.multiple.datasources.repository.servers"} ) public class ServersConfig { 的值也不同为了让spring将每个entityManager分开。

Parameter 0 of constructor in org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration required a single bean, but 2 were found:

第3。将一个数据源设置为主要

为了避免错误消息:Servers只需将其中一个数据源设置为@Primary,在本例中我选择@Bean("serversDataSourceProperties") @Primary @ConfigurationProperties("app.datasource.servers") public DataSourceProperties serversDataSourceProperties(){ return new DataSourceProperties(); } @Bean("serversDataSource") @Primary @ConfigurationProperties("app.datasource.servers") public DataSource serversDataSource(@Qualifier("serversDataSourceProperties") DataSourceProperties serversDataSourceProperties) { return serversDataSourceProperties().initializeDataSourceBuilder().build(); } 数据源为主要数据:

Servers

如果您需要更多信息,请参阅每个配置的完整示例:

@Configuration @EnableJpaRepositories( entityManagerFactoryRef = "serversEntityManager", transactionManagerRef = "serversTransactionManager", basePackages = {"org.springdemo.multiple.datasources.repository.servers"} ) public class ServersConfig { @Bean(name = "serversEntityManager") public LocalContainerEntityManagerFactoryBean getServersEntityManager(EntityManagerFactoryBuilder builder, @Qualifier("serversDataSource") DataSource serversDataSource){ return builder .dataSource(serversDataSource) .packages("org.springdemo.multiple.datasources.domain.servers") .persistenceUnit("servers") .properties(additionalJpaProperties()) .build(); } Map<String,?> additionalJpaProperties(){ Map<String,String> map = new HashMap<>(); map.put("hibernate.hbm2ddl.auto", "create"); map.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect"); map.put("hibernate.show_sql", "true"); return map; } @Bean("serversDataSourceProperties") @Primary @ConfigurationProperties("app.datasource.servers") public DataSourceProperties serversDataSourceProperties(){ return new DataSourceProperties(); } @Bean("serversDataSource") @Primary @ConfigurationProperties("app.datasource.servers") public DataSource serversDataSource(@Qualifier("serversDataSourceProperties") DataSourceProperties serversDataSourceProperties) { return serversDataSourceProperties().initializeDataSourceBuilder().build(); } @Bean(name = "serversTransactionManager") public JpaTransactionManager transactionManager(@Qualifier("serversEntityManager") EntityManagerFactory serversEntityManager){ JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(serversEntityManager); return transactionManager; } } JPA配置

Domains

@Configuration @EnableJpaRepositories( entityManagerFactoryRef = "domainsEntityManager", transactionManagerRef = "domainsTransactionManager", basePackages = {"org.springdemo.multiple.datasources.repository.domains"} ) public class DomainsConfig { @Bean(name = "domainsEntityManager") public LocalContainerEntityManagerFactoryBean getdomainsEntityManager(EntityManagerFactoryBuilder builder ,@Qualifier("domainsDataSource") DataSource domainsDataSource){ return builder .dataSource(domainsDataSource) .packages("org.springdemo.multiple.datasources.domain.domains") .persistenceUnit("domains") .properties(additionalJpaProperties()) .build(); } Map<String,?> additionalJpaProperties(){ Map<String,String> map = new HashMap<>(); map.put("hibernate.hbm2ddl.auto", "create"); map.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect"); map.put("hibernate.show_sql", "true"); return map; } @Bean("domainsDataSourceProperties") @ConfigurationProperties("app.datasource.domains") public DataSourceProperties domainsDataSourceProperties(){ return new DataSourceProperties(); } @Bean("domainsDataSource") public DataSource domainsDataSource(@Qualifier("domainsDataSourceProperties") DataSourceProperties domainsDataSourceProperties) { return domainsDataSourceProperties.initializeDataSourceBuilder().build(); } @Bean(name = "domainsTransactionManager") public JpaTransactionManager transactionManager(@Qualifier("domainsEntityManager") EntityManagerFactory domainsEntityManager){ JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(domainsEntityManager); return transactionManager; } } JPA配置

application.properties

为了分隔每个数据源,我将配置放在app.datasource.domains.url=jdbc:h2:mem:~/test app.datasource.domains.driver-class-name=org.h2.Driver app.datasource.servers.driver-class-name=com.mysql.jdbc.Driver app.datasource.servers.url=jdbc:mysql://localhost:3306/v?autoReconnect=true&useSSL=false app.datasource.servers.username=myuser app.datasource.servers.password=mypass 文件中,如下所示:

ModifyEvent

如果您需要更多信息,请参阅以下文档:

Spring Documentation: howto-two-datasources

如何配置两个不同数据库的类似示例:github example

答案 1 :(得分:2)

@Daniel C.提供的答案是正确的。从我身边进行小的校正/观察。

    如果您不想将任何数据源标记为
  • @Primary ,则不需要 默认一个,否则是必需的。
  • 如果您要使用 @Bean 名称将任何 EntityManagerFactoryBean 定义为 entityManagerFactory ,则最好将其标记为 @Primary < / strong>,以避免冲突。
  • @ConfigurationProperties(“ app.datasource.servers”) 可以在类级别标记,而不是在方法级别定义。
  • 如果使用Spring,最好返回 HikariDataSource 作为数据源 引导2.x或更高版本已更改。
  • 确保为 jdbc-url 定义确切的属性, HikariDataSource 引用JDBC连接URL。

答案 2 :(得分:0)

我刚刚在github中为mysql添加了一个模块感知的多数据库感知库。需要添加一些应用程序属性才能完成。

文档和其他详细信息可以在以下位置找到:-

https://github.com/yatharthamishra0419/spring-boot-data-multimodule-mysql