gpt4 book ai didi

java - 多数据源 spring boot

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:47:23 24 4
gpt4 key购买 nike

我已经尝试了 几个小时 来让它工作,查看文档:

https://docs.spring.io/spring-boot/docs/current/reference/html/howto-data-access.html

...各种 stackoverflow 问题以及我能找到的尽可能多的其他内容。但是,这被证明是难以捉摸的(阅读,让我想用头撞墙)。非常欢迎任何帮助!

我需要连接到两个不同的数据库(听起来很简单?)并且我有一个使用 spring-boot-starter-data-jpa 依赖项的 Spring Boot Web 应用程序,这让事情开始了非常好使用单一数据源。现在我需要与第二个数据库交谈,但事情一直没有奏效。我以为我让它工作了一段时间,但事实证明一切都转到了主数据库。

我目前正在尝试在一个单独的“缩减”项目中进行这项工作,以尝试减少移动部件的数量,但仍然无法正常工作。

我有两个 @Configuration 类 - 每个数据源一个,这是第一个:

@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "firstEntityManagerFactory",
transactionManagerRef = "firstTransactionManager",
basePackages = {"mystuff.jpaexp.jpatest"})
public class DataConfiguration {
@Bean
@Primary
@ConfigurationProperties(prefix = "app.datasource1")
public DataSourceProperties firstDataSourceProperties() {
return new DataSourceProperties();
}

@Bean
@Primary
@ConfigurationProperties("app.datasource1")
public DataSource firstDataSource() {
return firstDataSourceProperties().initializeDataSourceBuilder().
driverClassName("org.postgresql.Driver").
url("jdbc:postgresql://localhost:5432/experiment1").
username("postgres").
password("postgres").
build();
}

@Primary
@Bean
public LocalContainerEntityManagerFactoryBean firstEntityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);

LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("mystuff.jpaexp.jpatest");
factory.setDataSource(firstDataSource());
factory.setPersistenceUnitName("ds1");
return factory;
}

@Primary
@Bean
public PlatformTransactionManager firstTransactionManager() {
return new JpaTransactionManager();
}
}

这是第二个:

@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "secondEntityManagerFactory",
transactionManagerRef = "secondTransactionManager",
basePackages = {"mystuff.jpaexp.jpatest2"})
public class Otherconfiguration {
@Bean
@ConfigurationProperties(prefix = "app.datasource2")
public DataSourceProperties secondDataSourceProperties() {
return new DataSourceProperties();
}

@Bean
@ConfigurationProperties("app.datasource2")
public DataSource secondDataSource() {
return secondDataSourceProperties().initializeDataSourceBuilder().
driverClassName("org.postgresql.Driver").
url("jdbc:postgresql://localhost:5432/experiment2").
username("postgres").
password("postgres").
build();
}

@Bean
public LocalContainerEntityManagerFactoryBean secondEntityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);

LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("mystuff.jpaexp.jpatest2");
factory.setDataSource(secondDataSource());
factory.setPersistenceUnitName("ds2");
return factory;
}

@Bean
public PlatformTransactionManager secondTransactionManager() {
return new JpaTransactionManager();
}
}

mystuff.jpaexp.jpatestmystuff.jpaexp.jpatest2 这两个包中,我有一个简单的 @EntityCrudRepository 应该分别与第一个和第二个数据源放在一起。

然后我有一个 main() 来测试:

@SpringBootApplication
@EnableAutoConfiguration(exclude = {WebMvcAutoConfiguration.class})
@ComponentScan("mystuff.jpaexp.*")
public class SpringbootCommandLineApp implements CommandLineRunner {
private final MyRepository myRepository;
private final OtherRepo otherRepo;

@Autowired
public SpringbootCommandLineApp(MyRepository myRepository, OtherRepo otherRepo) {
this.myRepository = myRepository;
this.otherRepo = otherRepo;
}

public static void main(String[] args) {
new SpringApplicationBuilder(SpringbootCommandLineApp.class)
.web(false)
.run(args);
}

@Override
public void run(String... args) throws Exception {
myRepository.save(new MyEntity("Goodbye or hello"));
myRepository.save(new MyEntity("What?"));
myRepository.save(new MyEntity("1,2,3..."));

myRepository.findAll().forEach(System.out::println);

otherRepo.save(new MyEntity2("J Bloggs"));
otherRepo.save(new MyEntity2("A Beecher"));
otherRepo.save(new MyEntity2("C Jee"));

otherRepo.findAll().forEach(x -> {
System.out.println("Name:" + x.getName() + ", ID: " + x.getId());
});
}
}

最后,application.properties 中的一些属性:

app.datasource1.driver-class-name=org.postgresql.Driver
app.datasource1.url=jdbc:postgresql://localhost:5432/experiment1
app.datasource1.username=postgres
app.datasource1.password=postgres

app.datasource2.driver-class-name=org.postgresql.Driver
app.datasource2.url=jdbc:postgresql://localhost:5432/experiment2
app.datasource2.username=postgres
app.datasource2.password=postgres

这些绝对没有效果 -- 事情似乎仍然由 spring.datasource.* 配置,这显然没有用。

最终输出:

2018-05-25 17:04:00.797  WARN 29755 --- [           main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
2018-05-25 17:04:00.800 INFO 29755 --- [ main] utoConfigurationReportLoggingInitializer :

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2018-05-25 17:04:00.803 ERROR 29755 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :

***************************
APPLICATION FAILED TO START
***************************

Description:

Cannot determine embedded database driver class for database type NONE

Action:

If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).


Process finished with exit code 1

我知道这里有很多代码,抱歉,谢谢!

最佳答案

好吧,花了很长时间,我认为有很多细微的问题,还有一些可以稍微简化的地方:

  • 只需要一个 DataSourceProperties - 两个数据源都可以使用它
  • @ConfigurationProperties 在 DataSource bean 定义中需要,而不是 DataSourceProperties bean
  • 认为 @ComponentScan("mystuff.jpaexp.*") 注释不正确,用简单的@ComponentScan 替换似乎修复一些 bean 定义的拾取
  • 我必须将 EntityManagerFactor 注入(inject)到 JpaTransactionManager 定义中:return new JpaTransactionManager(secondEntityManagerFactory().getObject());
  • 我添加了一个 JpaProperties bean,并明确地将这些属性拉入了一个 VendorAdapter

VendorAdapter/JpaProperties 的变化看起来像这样(JpaProperties 独立于供应商但它有一个 hibernateProperties 似乎很奇怪?!):

@Bean
public LocalContainerEntityManagerFactoryBean secondEntityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);

LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("...entity-package...");
factory.setDataSource(secondDataSource());
Map<String, String> props = new HashMap<>();
props.putAll(secondJpaProperties().getProperties());
props.putAll(secondJpaProperties().getHibernateProperties(secondDataSource()));
factory.setJpaPropertyMap(props);
factory.setPersistenceUnitName("ds2");
return factory;
}

@Bean
@ConfigurationProperties(prefix = "jpa.datsource2")
public JpaProperties secondJpaProperties() {
return new JpaProperties();
}

我认为这足以让事情继续下去。此外,让嵌入式 H2 实例焕然一新的各种属性的非常巧妙的默认设置不再起作用,因此我还必须明确所有 DB 属性:

jpa.datasource1.hibernate.ddl-auto=create
app.datasource1.driver-class-name=org.h2.Driver
app.datasource1.url=jdbc:h2:mem:primary
app.datasource1.username=
app.datasource1.password=

jpa.datasource2.hibernate.ddl-auto=create
app.datasource2.driver-class-name=org.h2.Driver
app.datasource2.url=jdbc:h2:mem:view
app.datasource2.username=
app.datasource2.password=

关于java - 多数据源 spring boot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50533350/

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