spring-数据 - 多个 DB:NoUniqueBeanDefinitionException 没有可用类型 'TransactionManager' 的合格 bean

spring-data - multiple DB: NoUniqueBeanDefinitionException No qualifying bean of type 'TransactionManager' available

我创建了一个 spring-data 项目(版本 = 2.5.5),有两个数据源 GitHub。只要我使用接口 CrudRepository.java,它就可以正常工作。但是当我尝试基于 SimpleJpaRepository.java 实现我自己的 DAO 时,我得到了错误

No qualifying bean of type 'org.springframework.transaction.TransactionManager' available: expected single matching bean but found 2: db1TransactionManager,db2TransactionManager

DB2Config.java(DB1Config.java 相同,但 bean 名称不是“2”而是“1”)

@Configuration
@PropertySource("classpath:db2-config.properties")
@EnableJpaRepositories(
        basePackages = "com.vscoding.jpa.db2.entity",
        entityManagerFactoryRef = "db2EntityManagerFactory",
        transactionManagerRef = "db2TransactionManager"
)
public class DB2Config {

  @Bean
  @ConfigurationProperties(prefix = "db2.datasource")
  public DataSource db2DataSource() {
    return DataSourceBuilder.create().build();
  }

  @Bean
  public FactoryBean<EntityManagerFactory> db2EntityManagerFactory(@Qualifier("db2DataSource") DataSource db2DataSource, Environment env){
    var em = new LocalContainerEntityManagerFactoryBean();
    var va = new HibernateJpaVendorAdapter();
    var properties = new HashMap<String,Object>();

    properties.put("hibernate.hbm2ddl.auto","create");
    em.setDataSource(db2DataSource);
    em.setPackagesToScan("com.vscoding.jpa.db2.entity");
    em.setJpaVendorAdapter(va);
    em.setJpaPropertyMap(properties);

    return em;
  }

  @Bean
  public PlatformTransactionManager db2TransactionManager(@Qualifier("db2EntityManagerFactory") FactoryBean<EntityManagerFactory> db2EntityManagerFactory) throws Exception {
    var tm = new JpaTransactionManager();

    tm.setEntityManagerFactory(db2EntityManagerFactory.getObject());

    return tm;
  }

  @Bean
  @Profile("with-init")
  public DataSourceInitializer dataSourceInitializer2(@Qualifier("db2DataSource") DataSource datasource) {
    var populator = new ResourceDatabasePopulator();
    populator.addScript(new ClassPathResource("db2.sql"));

    DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
    dataSourceInitializer.setDataSource(datasource);
    dataSourceInitializer.setDatabasePopulator(populator);

    return dataSourceInitializer;
  }
}

ProductCustomRepository.java

@Repository
@Transactional(transactionManager = "db2TransactionManager")
public class ProductCustomRepository extends SimpleJpaRepository<ProductEntity2, Integer> {
  private final EntityManager entityManager;

  public ProductCustomRepository(@Qualifier("db2EntityManagerFactory") EntityManager entityManager) {
    super(ProductEntity2.class, entityManager);
    this.entityManager = entityManager;
  }

  public List<ProductEntity2> customQuery() {
    var query = entityManager.createQuery("SELECT p FROM ProductEntity2 p WHERE p.name='special'",ProductEntity2.class);

    return query.getResultList();
  }
}

我希望 @Transactional(transactionManager = "db2TransactionManager") 会 select 正确 transactionManager,但也许我遗漏了什么。

ProductCustomRepositoryTest.java(测试重现错误)

@SpringBootTest
class ProductCustomRepositoryTest {
  @Autowired
  private ProductCustomRepository sut;

  @Test
  void customQuery() {
    //Given
    var special = new ProductEntity2("special");
    sut.save(special);

    //When
    var result = sut.customQuery();

    //Then
    assertTrue(result.contains(special));
  }
}

提前致谢。

正如 Simon 所说,我可以按照 https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations

解决错误

将我的 ProductCustomRepository.java 更改为 CustomRepositoryImpl.java 并添加了界面 CustomRepository.java

@Repository
@Transactional(transactionManager = "db2TransactionManager")
public class CustomRepositoryImpl implements CustomRepository {
  // no changes here
}

然后用接口扩展我的主存储库。

public interface ProductRepository2 extends CrudRepository<ProductEntity2,Integer>,CustomRepository {
}