0

I have a number of JPA repositories classes and I want to create one common class where I will create a getter method of a respective repository and I will use that common class in the service layer. So Can you please guide me with best practices that how can I achieve this?

Here I am sharing my idea by using sample code,

JPA repository

@Repository
public interface IConfigRepository extends JpaRepository<Config, Integer> {  
}

public interface IBusinessRepository extends JpaRepository<Business, Integer> {
}

Repo Factory (Common Class for all repositories)

public class RepoFactory {
    @Autowired
    private IConfigRepository configRepo;
    
     @Autowired
    private IBusinessRepository businessRepo;
   
    public IConfigRepository getConfigRepository() {
        return configRepo;
    }
    
    public IBusinessRepository getBusinessRepository() {
        return businessRepo;
    }
}

Service Class

@Service
public class ServiceA {
  public final RepoFactory repoFactory;

   public ServiceA(RepoFactory repoFactory) {
       this.repoFactory = repoFactory
   }

   @Transactional(rollbackOn = Exception.class)
   public void saveOrUpdate(Config config) {
      repoFactory.getConfigRepository().save(config);
   }
}


@Service
public class ServiceB {
  public final RepoFactory repoFactory;

   public ServiceB(RepoFactory repoFactory) {
       this.repoFactory = repoFactory
   }

   @Transactional(rollbackOn = Exception.class)
   public void saveOrUpdate(Business reqBusiness) {
      repoFactory.getBusinessRepository().save(reqBusiness);
   }
}

Thanks, everyone for helping me in advance.

  • What is an ultimate goal of this action? – Yuriy Tsarkov May 20 '21 at 07:28
  • The ultimate goal is that I should access all repository classes by using a single common class such as RepoFactory. Is it possible? Is it good practice to follow? – Nisarg Raval May 20 '21 at 07:46
  • _Is it good practice to follow?_ Actually not. Each service should contain only repos that would be used in there. Where is a profit? All the spring repositories are in the context at any way. The only case with an inmlementation like yours that I can imagine is something like a generic customization. If you truly need it look at [that topic](https://stackoverflow.com/questions/14266089/how-to-retrieve-spring-data-repository-instance-for-given-domain-class) – Yuriy Tsarkov May 20 '21 at 08:17

1 Answers1

0

It looks like, you're trying to do something the @Profile annotation can help you with. If I were you, I would keep a common interface (not class) and make the IConfigRepository extend it. Then you can mark IConfigRepository with the @Profile annotation. If in the future, you have to write an analogue interface, you should also mark it with the @Profile annotation and you can switch between these interfaces anytime you want by setting the appropriate profile to active.

@Repository
@Profile("config")
public interface IConfigRepository extends CommonRepository, JpaRepository<Config,Integer> {  
}

public interface CommonRepository {  
}

@Service
public class ServiceA {
  public final CommonRepository commonRepository;

   public ServiceA(CommonRepository commonRepository) {
       this.commonRepository = commonRepository
   }

  ...
}
wolfhunter
  • 33
  • 7