SpringBoot多数据源JPA
我有以下代码 实体SpringBoot多数据源JPA,jpa,spring-boot,spring-data-jpa,Jpa,Spring Boot,Spring Data Jpa,我有以下代码 实体 @Entity public class Employee { @Id @GeneratedValue long id; @Column(name="first_name") String firstName; @Column(name="last_name") String lastName; @Column(name="sala
@Entity
public class Employee {
@Id
@GeneratedValue
long id;
@Column(name="first_name")
String firstName;
@Column(name="last_name")
String lastName;
@Column(name="salary")
int salary;
@ManyToOne
@JoinColumn(name="address")
Address address;
..... setter & getter
}
@Configuration
@EnableJpaRepositories(basePackages="com.example",
entityManagerFactoryRef = "primaryEntityManagerFactory")
public class DataSourceConfiguration {
@Bean(name="primaryDataSource")
@Primary
@ConfigurationProperties(prefix = "datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@Primary
public JpaTransactionManager transactionManager() {
JpaTransactionManager tm = new JpaTransactionManager();
tm.setEntityManagerFactory(primaryEntityManagerFactory().getObject());
return tm;
}
@Bean(name="primaryEntityManagerFactory")
@Primary
LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory() {
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
jpaVendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(primaryDataSource());
factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
factoryBean.setPackagesToScan(DataSourceConfiguration.class.getPackage().getName());
return factoryBean;
}
}
回购
public interface EmpRepository extends JpaRepository<Employee, Long>{}
辅助数据源配置
@Configuration
@EnableJpaRepositories(basePackages="com.example",
entityManagerFactoryRef = "secondaryEntityManagerFactory")
public class DS2Configuration {
@Bean(name="secondaryDataSource")
@ConfigurationProperties(prefix = "datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager tm = new JpaTransactionManager();
tm.setEntityManagerFactory(secondaryEntityManagerFactory().getObject());
return tm;
}
@Bean(name="secondaryEntityManagerFactory")
LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory() {
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
jpaVendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(secondaryDataSource());
factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
factoryBean.setPackagesToScan(DataSourceConfiguration.class.getPackage().getName());
return factoryBean;
}
}
应用程序属性
spring.jpa.show-sql = true
spring.jpa.properties.hibernate.show_sql=true
spring.jooq.sql-dialect=MYSQL
logging.level.org.springframework.data=DEBUG
# Primary DataSource configuration
datasource.primary.url=jdbc:mysql://127.0.0.1:3306/jpa
datasource.primary.username=root
datasource.primary.password=root
# Secondary DataSource configuration
datasource.secondary.url=jdbc:mysql://127.0.0.1:3306/jpa2
datasource.secondary.username=root
datasource.secondary.password=root
# Disable Spring DataSource auto-initialization
spring.datasource.initialize=false
server.port=8081
当我从EmpService实际运行函数findAll()时,它总是使用主数据源,即使我将次要entitymanagefactory指定为
@Autowired
@Qualifier("secondaryEntityManagerFactory")
EntityManager em;
如何解决这个问题?
请不要为此分享博客链接 之所以发生这种情况,是因为存在多个类型为javax.persistence.EntityManagerFactory的bean,以帮助spring boot决定选择哪个bean 用
@primary
注释bean
发生这种情况是因为存在多个类型为javax.persistence.EntityManagerFactory的bean,它们可以帮助spring boot决定选择哪个bean 用
@primary
注释bean
您需要在此方法上添加@Primary:primaryEntityManagerFactory() 顺便说一下,我认为primaryTransactionManager()和等效的二级方法是多余的,工厂bean方法返回同样的结果 您还需要根据entityManager定义transactionManager,例如
@Bean
@Primary
public JpaTransactionManager transactionManager() {
JpaTransactionManager tm = new JpaTransactionManager();
tm.setEntityManagerFactory(yourPrimaryEntityManagerInjected);
return tm;
}
您需要在此方法上添加@Primary:primaryEntityManagerFactory() 顺便说一下,我认为primaryTransactionManager()和等效的二级方法是多余的,工厂bean方法返回同样的结果 您还需要根据entityManager定义transactionManager,例如
@Bean
@Primary
public JpaTransactionManager transactionManager() {
JpaTransactionManager tm = new JpaTransactionManager();
tm.setEntityManagerFactory(yourPrimaryEntityManagerInjected);
return tm;
}
您需要将存储库类放在两个不同的目录中。并更改
@EnableJpaRepositories(basePackages="com.example".....)
在您配置数据源的两个位置中的行。这将解决您的问题代码运行但始终使用主数据源
关于您需要将存储库类放在两个不同的目录中。并更改
@EnableJpaRepositories(basePackages="com.example".....)
在您配置数据源的两个位置中的行。这将解决您的问题代码运行但始终使用主数据源
关于它抱怨的是非唯一的EntityManager工厂,而不是数据源。他的数据源设置看起来不错。它抱怨的是非唯一的EntityManagerFactory而不是数据源。他的数据源设置看起来不错。您需要为每个实体管理器定义一个事务管理器bean。我将把它添加到我的回复中。完成此操作。@Bean(name=“primaryTransactionManager”)@Primary public JpaTransactionManager primaryTransactionManager(){JpaTransactionManager tm=new JpaTransactionManager();tm.setEntityManagerFactory(primarytEntityManagerFactory().getNativeEntityManagerFactory());return tm;}但仍然是相同的错误同样当我从两个配置文件中删除transactionManager定义时,代码运行但始终使用主数据源,即使我使用@Autowired@Qualifier(“secondaryEntityManagerFactory”)EntityManager em在服务类上指定了次要数据源;打开org.springframework的debug并查看自动连线是如何发生的。就事务管理器而言,为其提供单独的java配置,而不是执行primaryEntityManagerFactory().getNativeEntityManageractory()只需使用注入工厂,即此primaryEntityManagerFactory。祝你好运,调试日志应该可以帮助你了解发生了什么。现在没有错误了。我在两个配置中都添加了transactionManager。但问题是每次它都在使用主数据源。我现在缺少什么?您需要为每个实体管理器定义一个事务管理器bean。我将把它添加到我的回复中。完成此操作。@Bean(name=“primaryTransactionManager”)@Primary public JpaTransactionManager primaryTransactionManager(){JpaTransactionManager tm=new JpaTransactionManager();tm.setEntityManagerFactory(primarytEntityManagerFactory().getNativeEntityManagerFactory());return tm;}但仍然是相同的错误同样当我从两个配置文件中删除transactionManager定义时,代码运行但始终使用主数据源,即使我使用@Autowired@Qualifier(“secondaryEntityManagerFactory”)EntityManager em在服务类上指定了次要数据源;打开org.springframework的debug并查看自动连线是如何发生的。就事务管理器而言,为其提供单独的java配置,而不是执行primaryEntityManagerFactory().getNativeEntityManageractory()只需使用注入工厂,即此primaryEntityManagerFactory。祝你好运,调试日志应该可以帮助你了解发生了什么。现在没有错误了。我在两个配置中都添加了transactionManager。但问题是每次它都在使用主数据源。我现在错过了什么?是的,成功了。但是给两个配置文件提供相同的basePackage并在运行时指定config是不可能的。我不确定,因为@componentscan基本上与包一起工作。但是查看文档(),您可以尝试使用excludeFilters。我没有亲自尝试过。让我知道它是否有效:)是的,它有效。但是给两个配置文件提供相同的basePackage并在运行时指定config是不可能的。我不确定,因为@componentscan基本上与包一起工作。但是查看文档(),您可以尝试使用excludeFilters。我没有亲自尝试过。让我知道它是否有效:)