这是我正在尝试使用Spring Data JPA实现类似解决方案的代码。
CustomerDbConfig.java(第一个数据源连接)
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "orderEntityManager",
transactionManagerRef = "orderTransactionManager",
basePackages = {"com.mm.repository.customer"})
public class CustomerDbConfig {
@Bean(name = "customerEntityManager")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] {"com.mm.domain.customer"});
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalJpaProperties());
em.setPersistenceUnitName("customerPersistence");
em.setPackagesToScan("com.mm.domain.customer");
return em;
}
Properties additionalJpaProperties(){
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
properties.setProperty("hibernate.show_sql", "true");
return properties;
}
@Bean
public DataSource dataSource(){
return DataSourceBuilder.create()
.url("jdbc:h2:mem:customer:H2")
.driverClassName("org.h2.Driver")
.username("sa")
.password("")
.build();
}
@Bean(name = "customerTransactionManager")
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
}
CustomerDbConfig.java(第二个数据源)
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "orderEntityManager",
transactionManagerRef = "orderTransactionManager",
basePackages = {"com.mm.repository.customer"})
public class CustomerDbConfig {
@Bean(name = "customerEntityManager")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] {"com.mm.domain.customer"});
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalJpaProperties());
em.setPersistenceUnitName("customerPersistence");
em.setPackagesToScan("com.mm.domain.customer");
return em;
}
Properties additionalJpaProperties(){
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
properties.setProperty("hibernate.show_sql", "true");
return properties;
}
@Bean
public DataSource dataSource(){
return DataSourceBuilder.create()
.url("jdbc:h2:mem:customer:H2")
.driverClassName("org.h2.Driver")
.username("sa")
.password("")
.build();
}
@Bean(name = "customerTransactionManager")
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
}
...
Customer.java(模型)
...
@Entity
@Table(name = "customer")
@Data
@EqualsAndHashCode(exclude = {"id"})
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "age", nullable = false)
private Integer age;
....
Order.java(模型)
@Entity
@Table(name = "order")
@Data
@EqualsAndHashCode(exclude = {"id"})
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(name = "code", nullable = false)
private Integer code;
@Column(name = "quality", nullable = false)
private Integer quality;
…
CustomerRepository.java
public interface CustomerRepository extends JpaRepository<Customer, Integer>{
}
OrderRepository.java
public interface OrderRepository extends JpaRepository<Order, Integer> {
}
最后,Application.java
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application extends SpringApplication{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public ServletRegistrationBean h2Console() {
ServletRegistrationBean reg = new ServletRegistrationBean(new WebServlet(), "/console/*");
reg.setLoadOnStartup(1);
return reg;
}
}
在启动过程中会引发以下异常:
-10-10 15:45:24.757 ERROR 1549 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customerTransactionManager' defined in class path resource [com/mm/boot/multidb/CustomerConfig.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [javax.persistence.EntityManagerFactory]: : No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: customerEntityManager,orderEntityManager; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: customerEntityManager,orderEntityManager
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:747)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:462)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1095)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:990)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:706)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
at com.mm.boot.multidb.Application.main(Application.java:17)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: customerEntityManager,orderEntityManager
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:974)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:811)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:739)
... 18 common frames omitted
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customerTransactionManager' defined in class path resource [com/mm/boot/multidb/CustomerConfig.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [javax.persistence.EntityManagerFactory]: : No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: customerEntityManager,orderEntityManager; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: customerEntityManager,orderEntityManager
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:747)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:462)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1095)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:990)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:706)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
at com.mm.boot.multidb.Application.main(Application.java:17)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: customerEntityManager,orderEntityManager
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:974)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:811)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:739)
... 18 more
预先感谢你的帮助。
通过使用@EnableAutoConfiguration和application.properties,还有另一种具有多个数据源的方法。
基本上,将多个dataSource配置信息放在application.properties上,并通过@EnableAutoConfiguration自动为第一个dataSource生成默认设置(dataSource和EntityManagerFactory)。但是对于下一个dataSource,请通过属性文件中的信息手动创建dataSource,entityManagerFactory和transactionManager。
下面是我设置两个数据源的示例。第一个数据源由@EnableAutoConfiguration设置,只能分配给一个配置,不能分配给多个。然后将通过DataSourceTransactionManager生成“ transactionManager” ,该外观看起来是由注释生成的默认transactionManager。但是,我已经看到,仅对于默认的DataSourceTransactionManager以及在有多个事务管理器的情况下,调度线程池中的线程上的事务才不会开始出现问题。所以我通过JpaTransactionManager手动创建transactionManager也为第一个dataSource分配了“ transactionManager” Bean名称和默认的entityManagerFactory。用于第一个数据源的JpaTransactionManager确实可以解决ScheduledThreadPool中线程上的奇怪事务问题。
Spring Boot 1.3.0.RELEASE的更新
我发现我以前使用@EnableAutoConfiguration的默认dataSource配置在使用Spring Boot 1.3版本查找entityManagerFactory时遇到问题。引入我自己的transactionManager之后,也许@EnableAutoConfiguration不会生成默认的entityManagerFactory。所以现在我自己创建了entityManagerFactory。因此,我不需要使用@EntityScan。因此,看起来我通过@EnableAutoConfiguration获得的安装越来越少。
第二个数据源是在没有@EnableAutoConfiguration的情况下设置的,并通过手动方式创建了“ anotherTransactionManager”。
由于从PlatformTransactionManager扩展了多个transactionManager,因此我们应在每个@Transactional注释上指定要使用的transactionManager
默认存储库配置
@Configuration
@EnableTransactionManagement
@EnableAutoConfiguration
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactory",
transactionManagerRef = "transactionManager",
basePackages = {"com.mysource.repository"})
public class RepositoryConfig {
@Autowired
JpaVendorAdapter jpaVendorAdapter;
@Autowired
DataSource dataSource;
@Bean(name = "entityManager")
public EntityManager entityManager() {
return entityManagerFactory().createEntityManager();
}
@Primary
@Bean(name = "entityManagerFactory")
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource);
emf.setJpaVendorAdapter(jpaVendorAdapter);
emf.setPackagesToScan("com.mysource.model");
emf.setPersistenceUnitName("default"); // <- giving 'default' as name
emf.afterPropertiesSet();
return emf.getObject();
}
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager() {
JpaTransactionManager tm = new JpaTransactionManager();
tm.setEntityManagerFactory(entityManagerFactory());
return tm;
}
}
另一个存储库配置
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "anotherEntityManagerFactory",
transactionManagerRef = "anotherTransactionManager",
basePackages = {"com.mysource.anothersource.repository"})
public class AnotherRepositoryConfig {
@Autowired
JpaVendorAdapter jpaVendorAdapter;
@Value("${another.datasource.url}")
private String databaseUrl;
@Value("${another.datasource.username}")
private String username;
@Value("${another.datasource.password}")
private String password;
@Value("${another.dataource.driverClassName}")
private String driverClassName;
@Value("${another.datasource.hibernate.dialect}")
private String dialect;
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource(databaseUrl, username, password);
dataSource.setDriverClassName(driverClassName);
return dataSource;
}
@Bean(name = "anotherEntityManager")
public EntityManager entityManager() {
return entityManagerFactory().createEntityManager();
}
@Bean(name = "anotherEntityManagerFactory")
public EntityManagerFactory entityManagerFactory() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", dialect);
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource());
emf.setJpaVendorAdapter(jpaVendorAdapter);
emf.setPackagesToScan("com.mysource.anothersource.model"); // <- package for entities
emf.setPersistenceUnitName("anotherPersistenceUnit");
emf.setJpaProperties(properties);
emf.afterPropertiesSet();
return emf.getObject();
}
@Bean(name = "anotherTransactionManager")
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager(entityManagerFactory());
}
}
application.properties
# database configuration
spring.datasource.url=jdbc:h2:file:~/main-source;AUTO_SERVER=TRUE
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.continueOnError=true
spring.datasource.initialize=false
# another database configuration
another.datasource.url=jdbc:sqlserver://localhost:1433;DatabaseName=another;
another.datasource.username=username
another.datasource.password=
another.datasource.hibernate.dialect=org.hibernate.dialect.SQLServer2008Dialect
another.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
为@Transactional注释选择适当的transactionManager
第一数据源服务
@Service("mainService")
@Transactional("transactionManager")
public class DefaultDataSourceServiceImpl implements DefaultDataSourceService
{
//
}
为另一个数据源提供服务
@Service("anotherService")
@Transactional("anotherTransactionManager")
public class AnotherDataSourceServiceImpl implements AnotherDataSourceService
{
//
}
我需要创建一个Camel路由,它轮询一个数据库,转换检索到的数据,然后将新实体插入另一个数据库。我需要帮助配置。 为什么它要寻找persistence.xml文件而不是使用注释?我使用的是Spring Boot1.5.13,与Camel 2.21.1一起发布。
我正在尝试使用两个数据源与我的SpringBoot应用程序,但无法获得第二个数据源自动连接。我尝试过很多事情,但这是我最接近的一次: 我的Yaml文件: 这是我到目前为止最接近的一次。我之所以说它是最接近的,是因为如果我删除@qualifier,那么我的两个dao方法实际上都可以工作,假设SECOND_SELECT语句对于我的DB1是有效的SQL语句。当我为非主datasouce输入@Qualif
我在Spring Boot中有两个MySQL数据源,因此我有两个配置类。但它似乎只使用主数据源。所有实体都是为主数据源创建的,因此crawlerdb和userdb实体都是在userdb中创建的。 我的userdb主配置: 我的辅助爬网数据库配置: 两个架构的实体类位于不同的包中,如类名上方的EntityScan所示。但当我检查MySQL workbench中创建的模式时,我看到所有实体都是在use
我正在尝试在Heroku上部署我的Quarkus-app。它工作正常,但我需要使用固定值指定数据源参数。因为Heroku可能会旋转此参数,所以这不是一个真正的好主意。 在Quarkus中,我需要应用程序中的这3个参数。属性: Heroku只给了我1个环境变量(
我有一个简单的Spring引导应用程序与2个外部罐子。每个jar都使用Spring JPA,并且完全配置为独立工作。 JAR1 这是我的Spring Boot应用程序的启动类 服务器启动时没有任何问题,但在配置jpa内容时存在一些问题。持久性单元ais的配置应使用Oracle方言和驱动程序。看来它拿起了JAR1的配置。 下一个问题是数据库访问。Spring不知道应该使用哪个事务管理器
本文向大家介绍springboot + mybatis配置多数据源示例,包括了springboot + mybatis配置多数据源示例的使用技巧和注意事项,需要的朋友参考一下 在实际开发中,我们一个项目可能会用到多个数据库,通常一个数据库对应一个数据源。 代码结构: 简要原理: 1)DatabaseType列出所有的数据源的key---key 2)DatabaseContextHolder是一个线