When I have lot of repositories interface I usually use a wrapper like this :
@Component
public class RepositoryContainer(){
@Autowired
public Myrepo1 repo1;
@Autowired
public Myrepo2 repo2;
//and so on....
}
Then I use it :
@Service
public class Myservice(){
@Autowired
RepositoryContainer repos;
public void service1(){
repos.repo1.findBy...
}
}
The problem is this way of doing generates many files, since each repository is an interface, so I have same files for repositories as for entities.
To reduce the number of files I tried using nested interfaces :
@Repository
public class RepositoryContainer(){
public interface Myrepo1 extends JpaRepository<Entity1, Long> {
}
public interface Myrepo2 extends JpaRepository<Entity2, Long> {
}
//and so on...
}
Now I am struggle because I can't access my repositories outside the class. Is there a way to do this :
@Service
public class Myservice(){
@Autowired
RepositoryContainer repos;
public void service1(){
//I would like to do this :
repos.Myrepo1.findBy...
}
}
Note that I've already enabled nested discovery repositories in
@EnableJpaRepositories( considerNestedRepositories = true )
Thanks a lot
Just turn on parameter considerNestedRepositories
in EnableJpaRepositories
annotation:
@SpringBootApplication
@EnableJpaRepositories(considerNestedRepositories = true)
public class Application {
//...
}
And then you will be able to inject your 'inner' repo:
@Service
public class Myservice(){
@Autowired Myrepo1 myrepo1;
@Autowired Myrepo2 myrepo2;
public void service1() {
myrepo1.findBy...
myrepo2.findBy...
}
}
I think that there isn't another variant...
UPDATE
If the goal is to have a kind of 'clean code' I can propose a kind of approach:
public interface MyRepo1 extends JpaRepository<Entity1, Long> {
}
public interface MyRepo2 extends JpaRepository<Entity2, Long> {
}
@Getter
@RequiredArgsConstructor
@Component
public class RepoContainer {
private final MyRepo1 myRepo1;
private final MyRepo2 myRepo2;
}
@RequiredArgsConstructor
@Service
public class MyService() {
private final RepoContainer repoContainer;
public void method() {
repoContainer.getMyRepo1().findBy(...);
repoContainer.getMyRepo2().findBy(...);
}
}
After discussion with @Cepro0 here my solution :
@Repository
public class RepositoryContainer(){
public interface Myrepo1 extends JpaRepository<Entity1, Long> {
}
public interface Myrepo2 extends JpaRepository<Entity2, Long> {
}
//I am using an inner bean to get my repositories
@Component
public class Container{
@Autowired
public Myrepo1 repo1;
@Autowired
public Myrepo2 repo2;
}
}
Then :
@Service
public class Myservice(){
@Autowired
RepositoryContainer.Container repos;
public void service1(){
repos.repo1.findBy...
}
}
This works perfectly and since today this is how I will proceed for reducing the number of file for each repository's interface and having a clean code because sometimes we need many repositories in a service and we have to inject them one-by-one.
If someone sees some drawbacks, please let me know.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With