【问题标题】:Spring Data JPA: Instantiate multiple repositories from same repository interface definitions, each pointing to a different databaseSpring Data JPA:从相同的存储库接口定义实例化多个存储库,每个存储库指向不同的数据库
【发布时间】:2016-04-28 14:06:44
【问题描述】:

我有一组实体类和存储库定义以及 N 个数据库,所有这些都有架构。如何实例化指向 N 个数据库中的每一个的 N 个存储库。

@Entity
public class Student {
}

public interface StudentRepository extends JpaRepository< Student, Long> {
}

制作与数据库数量一样多的存储库接口副本 (http://www.baeldung.com/spring-data-jpa-multiple-databases) 和使用动态数据源路由 (http://spring.io/blog/2007/01/23/dynamic-datasource-routing/) 是我找到的两个解决方案。

但是,我需要的是类似的东西

@Component
public class Foo {

    @Autowired
    StudentRepository studentRepositoryForDatabase1;
    @Autowired
    StudentRepository studentRepositoryForDatabase2;

}

这可行吗?

【问题讨论】:

标签: java spring jpa spring-data spring-data-jpa


【解决方案1】:

N 有多大?如果不应该创建类N 次,您可能必须自己实例化SimpleJpaRepository(Class&lt;T&gt; domainClass, EntityManager em)(否则使用interface)。您可以在那里传递所需数据库的EntityManager

伪代码,但它通常应该像这样工作:

//maybe spring is capable of injecting all ems here?
@Autowired
private List<EntityManager> ems;

@Autowired
private ApplicationContext ctx;

@Autowired
private ConfigurableBeanFactory bf;

int n = 10;
for (int i = 0; i < n; i++) {
    //you'd probably need a way to identify which "em" maps to which number
    CrudRepository dao = new YourBeanRepository(YourBean.class, emN);
    bf.registerSingleton("YourBean" + n, dao);
}

ctx.getBean("YourBean1");

一个附带问题:为什么您有多个具有相同架构的数据库?如果您想提供更多详细信息,可能您的应用程序或数据库设计在这里不正确。

更新:你可以试试这样的:

public class YourBeanRepository<T> extends SimpleJpaRepository<T> {
    //repo containing your findFirstBy()...
    @Autowired
    private StudentRepository dao; //provide a getter

    public YourBeanRepository(Class<T> clazz, EntityManager em) {
        super(clazz, em);
    }
}

【讨论】:

  • 自动装配 @Autowired StudentRepository studentRepositoryForDatabase1;失败,因为创建的存储库的类型为 SimpleJpaRepository 而不是 StudentRepository。另外,如果按照这种创建repositories的方法,是否表示repository不能包含findByFirstName(String)等方法(其实现由Spring data提供)?
  • 当然你必须连接@Autowired @Qualifier("YourBean1"),否则spring没有机会检测到所需的方法。或者只是注入ApplicationContext 并使用ctx.getBean("YourBean1"); 来选择所需的bean,这可能比创建StudentRepository 的N@Autowired 成员变量要好得多。关于您的第二个问题,请参阅我的更新。
  • 我添加了限定符注释,但它不起作用@Qualifier("studentRepository1") @Autowired StudentRepositorystudentRepository1; 我得到的错误是Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [kb.repo.StudentRepository ] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value=studentRepository1), @org.springframework.beans.factory.annotation.Autowired(required=true)}
  • 如所写:如果您不想创建 StudentRepository 的 N 类,那么您也不应该创建 N 自动装配变量。您不能在类文件端保存样板,然后在代码端添加样板。我会在你的服务类中使用ctx.getBean(),而不自动装配N
  • 另一个更新:您可以尝试将interface StudentRepository 添加到YourBeanRepository。也许您必须在创建new YourBeanRepository() 之后使用setter 来执行此操作。然后向注入的接口提供getter 以访问您的findByX()方法。
猜你喜欢
  • 2015-02-13
  • 1970-01-01
  • 2018-10-06
  • 1970-01-01
  • 1970-01-01
  • 2018-03-30
  • 1970-01-01
  • 2013-05-09
  • 1970-01-01
相关资源
最近更新 更多