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