Ranjith
Ranjith

Reputation: 1739

Spring Data JPA: Instantiate multiple repositories from same repository interface definitions, each pointing to a different database

I have a set of entity classes and repository definitions and N databases, all of which have the schema. How can I instantiate N repositories pointing to each of the N databases.

@Entity
public class Student {
}

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

Making as many copies of repository interfaces as the number of databases (http://www.baeldung.com/spring-data-jpa-multiple-databases) and using dynamic datasource routing (http://spring.io/blog/2007/01/23/dynamic-datasource-routing/) were two solutions I found.

But, what I need is something like

@Component
public class Foo {

    @Autowired
    StudentRepository studentRepositoryForDatabase1;
    @Autowired
    StudentRepository studentRepositoryForDatabase2;

}

Is this feasible?

Upvotes: 3

Views: 2404

Answers (1)

membersound
membersound

Reputation: 86915

How large is N? If classes should not be created N times, you'd probably have to instantiate SimpleJpaRepository(Class<T> domainClass, EntityManager em) yourself (which otherwise is the interface used for). There you can pass the EntityManager of your desired database.

Pseudo code, but it should in general work like this:

//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");

One sidequestion: why do you have multiple databases with the same schema? Maybe your application or database design is not correct here, if you might want to give futher details.

Update: you might try something like this:

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);
    }
}

Upvotes: 1

Related Questions