当前位置: 首页 > 知识库问答 >
问题:

Spring数据JPA-多个启用jparepositories

商勇
2023-03-14

描述:com.cavion.services.UserDataService中得字段userDataRepo需要一个名为“Entity ManagerFactory”得bean,但找不到该bean.操作:考虑在您的配置中定义一个名为'Entity ManagerFactory‘的bean。

我需要在我的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);
        }

    };
}}

共有1个答案

仲涵亮
2023-03-14

为了让spring知道什么datasource与什么repository相关,您应该在@enablejparepositories注释中定义它。假设我们有两个实体,servers实体和domains实体,每个实体都有自己的Repo,然后每个存储库都有自己的JpaDataSource配置。

1.根据与存储库相关的数据源对所有存储库进行分组。例如:

domains实体的存储库(包: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> {
}
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> {
}

2.对于需要定义配置的每个JPA数据Soruce,在本例中,我展示了如何配置两个不同的数据源

domainsJpa配置:数据源和存储库之间的关系在basePackages值中定义,这就是为什么需要根据每个回购将使用的实体管理器将存储库分组在不同的包中的原因。

@Configuration
@EnableJpaRepositories(
        entityManagerFactoryRef = "domainsEntityManager",
        transactionManagerRef = "domainsTransactionManager",
        basePackages = {"org.springdemo.multiple.datasources.repository.domains"}
        )
public class DomainsConfig {

servers数据源配置:如您所见,basePackages值具有servers存储库的包名称,并且EntityManagerFactoryRefTransactionManagerRef的值不同,以便spring将每个EntityManager分开。

@Configuration
@EnableJpaRepositories(
        entityManagerFactoryRef = "serversEntityManager",
        transactionManagerRef = "serversTransactionManager",
        basePackages = {"org.springdemo.multiple.datasources.repository.servers"}
        )
public class ServersConfig {

3.将一个数据源设置为主数据源

为了避免出现错误消息:org.springframework.boot.autocigure.orm.jpa.hibernatejpaAutoConfiguration中构造函数的参数0需要一个bean,但找到了2个:只是将其中一个数据源设置为@primary,在本例中,我选择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();
}

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

服务器JPA配置

@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配置

@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;
    }

}

为了分离每个数据源,我将配置放在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
 类似资料:
  • 问题内容: 我有一个Spring + Hibernate + JPA应用程序。用户登录时,可以从要连接的数据库列表中进行选择(这是要求)。所有数据库都有相同的架构,因此将使用相同的实体和DAO。 现在,我有一个EntityManager(目前正在使用一个数据库),它被注入到DAO中,如下所示: 有什么方法可以让DAO根据从服务层接收到的参数/属性自动接收entityManager(由Spring管

  • 问题内容: 我正在尝试配置Spring + Hibernate + JPA以使用两个数据库(MySQL和MSSQL)。 我的datasource-context.xml: 每个persistence.xml包含一个单元,如下所示: PersistenceUnitManager导致以下异常: 如果只留下一个没有列表的persistence.xml,则每个列表都可以正常工作,但我需要2个单元… 我还尝

  • 问题内容: 我需要创建一个可以管理多个数据源的服务。当首次运行应用程序时,这些数据源不一定存在,实际上,端点将创建新数据库,我希望能够切换到它们并创建数据。 例如,假设我有3个数据库,A,B和C,然后启动应用程序,使用创建D的端点,然后再使用D。 那可能吗? 我知道如何切换到其他数据源(如果存在),但是现在看不到任何解决方案可以使我的请求成为可能。你有什么主意吗? 谢谢 问题答案: 为了使用Spr

  • 我还向b_spring.xml声明了另一个entityManagetFactory、事务管理器和dataSource。 误差 bean初始化失败;嵌套异常是org.springframework.beans.factory.nosuchbeanDefinitionException:没有定义[javax.persistence.entityManagerFactory]类型的唯一bean:预期的单

  • 问题内容: 这是我正在尝试使用Spring Data JPA实现类似解决方案的代码。 CustomerDbConfig.java(第一个数据源连接) CustomerDbConfig.java(第二个数据源) Order.java(模型) … CustomerRepository.java 最后,Application.java 在启动过程中会引发以下异常: 预先感谢你的帮助。 问题答案: 通过使

  • 我正在使用spring数据jpa为我的服务实现多事务(数据库),带有两个持久的单元名。并在Jboss 6.4 EAP中部署 以下是我的服务详情 在Jboss中,我无法部署它,我遇到以下异常: 原因:org.springframework.beans.factory.BeanCreationException:无法自动装配字段:私有com.test.demo.domain.repository.Tb