Spring Data JPA-多个EnableJpaRepositories
我的应用程序具有多个数据源,因此我基于此URL创建了两个数据源配置类 。
但是在运行spring boot应用程序时出现错误
说明:com.cavion.services.UserDataService中的userDataRepo字段需要找不到名为’entityManagerFactory’的bean。行动:考虑在你的配置中定义一个名为“ entityManagerFactory”的bean。
从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启动类上给出了EnableJpaRepositories,所以如何配置多个EnableJpaRepositories以便可以配置多个entityManagerFactory?
请提出设置多个数据源的最佳方法。
回答:
为了让spring知道DataSource
与之相关的内容,Repository
你应该在@EnableJpaRepositories
注释中对其进行定义。假设我们有两个实体,Servers
实体和Domains
实体,并且每个实体都有自己的存储库,那么每个存储库都有自己的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 Data Soruce,你需要定义一个配置,在此示例中,我演示了如何配置两个不同的DataSources
DomainsJpa
配置:basePackages
值中定义了数据源与存储库之间的关系,这就是为什么有必要根据每个存储库将使用的实体管理器将存储库分组到不同程序包中的原因。
@Configuration@EnableJpaRepositories(
entityManagerFactoryRef = "domainsEntityManager",
transactionManagerRef = "domainsTransactionManager",
basePackages = {"org.springdemo.multiple.datasources.repository.domains"}
)
public class DomainsConfig {
Servers
数据源配置:正如你所看到的basePackages值具有的包名Servers
库,并且还值entityManagerFactoryRef
和transactionManagerRef
是为了让spring分隔每个EntityManager的不同。
@Configuration@EnableJpaRepositories(
entityManagerFactoryRef = "serversEntityManager",
transactionManagerRef = "serversTransactionManager",
basePackages = {"org.springdemo.multiple.datasources.repository.servers"}
)
public class ServersConfig {
3.将一个数据源设置为主数据库
为了避免出现错误消息:Parameter 0 of constructor in org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration required a single bean, but 2 were found:
只需将数据源之一设置为@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();
}
如果你需要更多信息,请参见每种配置的完整示例:
Servers 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;
}
}
Domains 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:~/testapp.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 Data JPA-多个EnableJpaRepositories 的全部内容, 来源链接: utcz.com/qa/420639.html