Spring JPA定义了多个EntityManagerFactory,但存储库仍然只访问一个数据库
每个人都说Spring JPA非常容易使用,但我想知道为什么它与多个数据源的关系如此复杂。 我正在尝试访问3个不同的数据库,并为相同和不同的存储库定义了相应的配置文件 Spring正在调用所有三个EntityManagerFactory,但当我在服务层访问它们时,我始终可以访问相同的db 是否仍然需要验证Autowired存储库是否指向正确的数据库 我的第一个数据库配置Spring JPA定义了多个EntityManagerFactory,但存储库仍然只访问一个数据库,spring,spring-mvc,spring-boot,spring-data,spring-data-jpa,Spring,Spring Mvc,Spring Boot,Spring Data,Spring Data Jpa,每个人都说Spring JPA非常容易使用,但我想知道为什么它与多个数据源的关系如此复杂。 我正在尝试访问3个不同的数据库,并为相同和不同的存储库定义了相应的配置文件 Spring正在调用所有三个EntityManagerFactory,但当我在服务层访问它们时,我始终可以访问相同的db 是否仍然需要验证Autowired存储库是否指向正确的数据库 我的第一个数据库配置 @Configuration @EnableTransactionManagement @EnableJpaReposit
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "xx.xx.xx.xx", entityManagerFactoryRef = "orangeEntityManagerFactory ", transactionManagerRef = "transactionManagerthree")
@PropertySource("classpath:application.properties")
public class TestDbConfig {
@Value("${spring.datasource.driver-class-name}")
String driverClassName = "";
@Value("${spring.datasource.url}")
String url = "";
@Value("${spring.datasource.username}")
String userName = "";
@Value("${spring.datasource.password}")
String password = "";
@Autowired
JpaVendorAdapter jpaVendorAdapter;
@Bean(name = "orangeEntityManager")
public EntityManager entityManager() {
return entityManagerFactory().createEntityManager();
}
@Bean(name = "orangeEntityManagerFactory")
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(DataSourceBuilder.create().url(url)
.driverClassName(driverClassName).username(userName)
.password(password).build());
factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
factoryBean.setPackagesToScan(R.orange_PACKAGE);
factoryBean.setPersistenceUnitName("orangePersistenceUnit");
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
@Bean(name = "orangeTransactionManager")
PlatformTransactionManager transactionManagerThree() {
return new JpaTransactionManager(entityManagerFactory());
}
}
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "xx.xx.xx.xx", entityManagerFactoryRef = "harvEntityManagerFactory ", transactionManagerRef = "transactionManagerOne")
@PropertySource("classpath:application.properties")
public class HarvDbConfig {
@Value("${spring.datasourceHarvhelo.driver-class-name}")
String driverClassName = "";
@Value("${spring.datasourceHarvhelo.url}")
String url = "";
@Value("${spring.datasourceHarvhelo.username}")
String userName = "";
@Value("${spring.datasourceHarvhelo.password}")
String password = "";
@Autowired
JpaVendorAdapter jpaVendorAdapter;
@Bean(name = "HarvEntityManager")
public EntityManager entityManager() {
return entityManagerFactory().createEntityManager();
}
@Bean(name = "HarvEntityManagerFactory")
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(DataSourceBuilder.create().url(url)
.driverClassName(driverClassName).username(userName)
.password(password).build());
factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
factoryBean.setPackagesToScan(R.HarvnDB_PACKAGE);
factoryBean.setPersistenceUnitName("HarvPersistenceUnit");
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
@Bean
PlatformTransactionManager transactionManagerOne() {
return new JpaTransactionManager(entityManagerFactory());
}
}
****第二数据库配置****
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "xx.xx.xx.xx", entityManagerFactoryRef = "cscheloEntityManagerFactory ", transactionManagerRef = "transactionManagertwo")
@PropertySource("classpath:application.properties")
public class cscDbConfig {
@Value("${spring.datasourcecschelo.driver-class-name}")
String driverClassName = "";
@Value("${spring.datasourcecschelo.url}")
String url = "";
@Value("${spring.datasourcecschelo.username}")
String userName = "";
@Value("${spring.datasourcecschelo.password}")
String password = "";
@Autowired
JpaVendorAdapter jpaVendorAdapter;
// @Bean(name = "cscheloDataSource")
// public DataSource dataSource() {
// return DataSourceBuilder.create().url(url)
// .driverClassName(driverClassName).username(userName)
// .password(password).build();
// }
@Bean(name = "cscheloEntityManager")
public EntityManager entityManager() {
return entityManagerFactory().createEntityManager();
}
@Bean(name = "cscheloEntityManagerFactory")
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(DataSourceBuilder.create().url(url)
.driverClassName(driverClassName).username(userName)
.password(password).build());
factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
factoryBean.setPackagesToScan(R.cscDB_PACKAGE);
factoryBean.setPersistenceUnitName("cscheloPersistenceUnit");
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
@Bean(name = "transactionManagertwo")
PlatformTransactionManager transactionManagerTwo() {
return new JpaTransactionManager(entityManagerFactory());
}
}
3rd db config
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "xx.xx.xx.xx", entityManagerFactoryRef = "orangeEntityManagerFactory ", transactionManagerRef = "transactionManagerthree")
@PropertySource("classpath:application.properties")
public class TestDbConfig {
@Value("${spring.datasource.driver-class-name}")
String driverClassName = "";
@Value("${spring.datasource.url}")
String url = "";
@Value("${spring.datasource.username}")
String userName = "";
@Value("${spring.datasource.password}")
String password = "";
@Autowired
JpaVendorAdapter jpaVendorAdapter;
@Bean(name = "orangeEntityManager")
public EntityManager entityManager() {
return entityManagerFactory().createEntityManager();
}
@Bean(name = "orangeEntityManagerFactory")
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(DataSourceBuilder.create().url(url)
.driverClassName(driverClassName).username(userName)
.password(password).build());
factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
factoryBean.setPackagesToScan(R.orange_PACKAGE);
factoryBean.setPersistenceUnitName("orangePersistenceUnit");
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
@Bean(name = "orangeTransactionManager")
PlatformTransactionManager transactionManagerThree() {
return new JpaTransactionManager(entityManagerFactory());
}
}
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "xx.xx.xx.xx", entityManagerFactoryRef = "harvEntityManagerFactory ", transactionManagerRef = "transactionManagerOne")
@PropertySource("classpath:application.properties")
public class HarvDbConfig {
@Value("${spring.datasourceHarvhelo.driver-class-name}")
String driverClassName = "";
@Value("${spring.datasourceHarvhelo.url}")
String url = "";
@Value("${spring.datasourceHarvhelo.username}")
String userName = "";
@Value("${spring.datasourceHarvhelo.password}")
String password = "";
@Autowired
JpaVendorAdapter jpaVendorAdapter;
@Bean(name = "HarvEntityManager")
public EntityManager entityManager() {
return entityManagerFactory().createEntityManager();
}
@Bean(name = "HarvEntityManagerFactory")
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(DataSourceBuilder.create().url(url)
.driverClassName(driverClassName).username(userName)
.password(password).build());
factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
factoryBean.setPackagesToScan(R.HarvnDB_PACKAGE);
factoryBean.setPersistenceUnitName("HarvPersistenceUnit");
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
@Bean
PlatformTransactionManager transactionManagerOne() {
return new JpaTransactionManager(entityManagerFactory());
}
}
我的存储库
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
@Query(value = "select * from orders where id=?1", nativeQuery = true)
Order getOrders(Long id);
@Query(value = "REPLACE INTO order ", nativeQuery = true)
void replaceIntoOrder(Order order);
Order findById(Long id);
}
@Repository
public interface cscOrderRepository extends JpaRepository<Order, Long> {
@Query(value = "select * from v_orders where old_id=?1 and ordertype_id=?2", nativeQuery = true)
Order findByIdndType(int id, int type);
}
@Repository
public interface HarvOrderRepository extends JpaRepository<Order, Long> {
@Query(value = "select * from v_orders where old_id=?1 and ordertype_id=?2", nativeQuery = true)
Order findByIdndType(int id, int type);
}
@存储库
公共接口OrderRepository扩展了JpaRepository{
@查询(value=“select*from orders,其中id=?1”,nativeQuery=true)
订单获取订单(长id);
@查询(value=“替换为订单”,nativeQuery=true)
无效替换订单(订单);
订单findById(长id);
}
@存储库
公共接口cscOrderRepository扩展了JpaRepository{
@查询(value=“select*from v_orders,其中old_id=?1和ordertype_id=?2”,nativeQuery=true)
订单findByIdndType(int-id,int-type);
}
@存储库
公共接口HarvOrderRepository扩展了JpaRepository{
@查询(value=“select*from v_orders,其中old_id=?1和ordertype_id=?2”,nativeQuery=true)
订单findByIdndType(int-id,int-type);
}
这就是我试图访问它们的方式
@Service
public class OrderService extends AbstractService<Order> {
@Autowired
OrderRepository orangeOrderRepository;
@Autowired
HarvOrderRepository ngheloOrderRepository;
@Autowired
cscOrderRepository cscheloOrderRepository;
@Override
public Order findById(Long id) throws EntityNotFoundException {
int idToBePassed = 123223;
int type = 1;
Order ngheloOrder = ngheloOrderRepository.findByIdndType(idToBePassed,
type);
Order cscheloOrder = cscheloOrderRepository.findByIdndType(
idToBePassed, type);
@服务
公共类OrderService扩展了AbstractService{
@自动连线
OrderRepository orangeOrderRepository;
@自动连线
HarvorderNgheloorderRepository;
@自动连线
cscheloorderepository;
@凌驾
公共秩序findById(长id)引发EntityNotFoundException{
int idToBePassed=123223;
int型=1;
订单ngheloOrder=Ngheloorderepositionary.findByIdndType(IDToPassed,
类型);
订单cscheloOrder=cscheloOrderRepository.findByIdndType(
idToPassed,类型);
从代码中可以看出,我正在从3个数据库自动连接所有3个存储库,我想从一个数据库获取数据并插入另一个数据库(根据我的要求),但当我尝试访问cscheloorderepositionory.findByIdndType时(
idToBePassed,type);它说表xyz不存在,因为它没有访问正确的EntityManagerFactory设置
此外,我不知道如何在存储库中手动自动连接EntityManagerFactory,我尝试了PersistentContext,但得到了未找到的异常
请提供您宝贵的反馈。我如何解决此问题,谢谢。包含此信息的persistence.xml文件
<persistence-unit name="MyAppPostgresPU">
<jta-data-source>jdbc/PostgresPool_test</jta-data-source>
<class>model.MyThing</class>
</persistence-unit>
<persistence-unit name="MyAppMySQLPU">
<jta-data-source>jdbc/MySQLPool_test</jta-data-source>
<class>model.MyThing</class>
</persistence-unit>
如果您没有在@EnableJpaRepositories的属性“entityManagerFactoryRef”中指定entityManagerFactory bean,则在上下文中找到的名为entityManagerFactory的entityManagerFactory bean会自动连接。它都在Spring数据JPA引用文档中 entityManagerFactoryRef:显式连接要与 repositories元素检测到的存储库。通常使用 如果在中使用了多个EntityManagerFactory bean 应用程序。如果未配置,我们将自动查找 中名为EntityManagerFactory的EntityManagerFactory bean 应用程序上下文 试试这个:
@EnableJpaRepositories(
basePackages = "xxx.xxx.xxx.entitiesfordb1",
entityManagerFactoryRef = "entityManagerForDB1",
transactionManagerRef = "transactionManagerForDB1"
)
请参见下面的示例
基本上,你的存储库需要在不同的包上。除了分布式事务,这是你想要的,我猜..检查这个@jay它没有帮助不幸的是,你的存储库在同一个包中吗?@Roxy差不多一年后,你有解决方案吗?我想我们应该在basePackage中定义存储库而不是实体。