gpt4 book ai didi

Spring Data JPA - 多个 EnableJpaRepositories

转载 作者:IT老高 更新时间:2023-10-28 13:51:24 29 4
gpt4 key购买 nike

我的应用程序有多个数据源,所以我基于这个 URL 创建了两个数据源配置类.

但是在运行 spring boot 应用程序时出现错误

Description:Field userDataRepo in com.cavion.services.UserDataService required a bean named 'entityManagerFactory' that could not be found.Action:Consider defining a bean named 'entityManagerFactory' in your configuration.

从此Question在 StackOverflow 上帮助我找出了问题。我需要在我的 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 boot 类上给出了 EnableJpaRepositories ,那么如何配置多个 EnableJpaRepositories 以便我可以配置多个 entityManagerFactory ?

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

最佳答案

为了让 spring 知道什么 DataSource 与什么 Repository 相关,你应该在 @EnableJpaRepositories 注释中定义它。假设我们有两个实体,Servers 实体和 Domains 实体,每个实体都有自己的 Repo,然后每个 Repository 都有自己的 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> {
}

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> {
}

<强>2。您需要为每个 JPA 数据源定义一个配置,在此示例中,我将展示如何配置两个不同的数据源

Domains Jpa 配置:数据源和存储库之间的关系在 basePackages 值中定义,这就是为什么需要将存储库分组到不同的包取决于每个 repo 将使用的实体管理器。

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

Servers 数据源配置:如您所见,basePackages 值具有 Servers Repository 的包名称,以及 entityManagerFactoryRef 的值> 和 transactionManagerRef 不同是为了让 spring 将每个 entityManager 分开。

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

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

为了避免错误信息:org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration 中构造函数的参数 0 需要单个 bean,但找到了 2 个: 只需设置其中之一数据源为@Primary,在此示例中,我选择 Servers 数据源作为主要数据源:

@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 Documentation: howto-two-datasources

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

关于Spring Data JPA - 多个 EnableJpaRepositories,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45663025/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com