title: Spring Data - one service class to handle common operations on entities (how to autowire JpaRepository)
body: <p><strong>Main question</strong> - I want to write a service (say CommonService) to handle common operations like find, count etc. for a range of entities (there is a reason why I cant use the JpaRepository out-of-box methods as explained below). How can I autowire a JpaRepository to achieve this? Details - </p>
  
  <p><strong>Complication</strong> - Now, due to business requirements, I have to associate a country ID with every entity (while saving, and use while retrieving etc.). I get this ID from the logged in user (i.e. not provided as part of saving or querying the entity) - so I cannot use (or expose via REST) the JpaRepository save or findOne directly - I have to go thru a service that does this and then saves/fetches using the JpaRepository.</p>
  
  <p><strong>Tech Stack</strong></p>
  
  <ol>
  <li>Spring data jpa 1.9.4 </li>
  <li>Spring boot 1.3.5 </li>
  <li>JPA provider hibernate</li>
  <li>DB - MySQL</li>
  </ol>
  
  <p>I have an abstract Base Entity - Fruit (with @MappedSuperclass) that all my fruit classes extend - e.g. Apple, Orange etc.</p>
  
  <p>I have a BaseRepository for common methods - </p>
  
  <pre><code>@NoRepositoryBean
  public interface BaseRepository&lt;T&gt; extends JpaRepository&lt;T, Long&gt; {
    /* common entity methods here */
    T findByIdAndCountryId(Long id, String countryId);
    Long countByIdAndCountryId(Long id, String countryId);
  }
  </code></pre>
  
  <p>That all the Fruit repositories extend - </p>
  
  <pre><code>public interface AppleRepository extends BaseRepository&lt;Apple&gt; {
    /* entity specific methods here */
  }
  
  public interface OrangeRepository extends BaseRepository&lt;Orange&gt; {
    /* entity specific methods here */
  }
  
  public interface BananaRepository extends BaseRepository&lt;Banana&gt; {
    /* entity specific methods here */
  }
  
  public interface GrapeRepository extends BaseRepository&lt;Grape&gt; {
    /* entity specific methods here */
  }
  </code></pre>
  
  <p>Now, due to business requirements (menthined in complication above), I have to have a service layer that does the save/fetche using the JpaRepository. Something like below - </p>
  
  <pre><code>public Fruit findMyFruit(Long id) {
      Fruit localFruit;
      String countryId = null;
  
      countryId = countryService.GetCountryIdForLoggedInUser();
  
      /* ?? how to autowire repository based on entity ?? */
      repository.findByIdAndCountryId(id, countryId);
  
      return localBaseEntity;
  }
  </code></pre>
  
  <p>In the case above, it is just about getting the countryId, other cases are more complicated hence I cannot (or do not want to) repeat them every time in the calling Controllers or services etc.</p>
  
  <p>If I use Generics and do the following, Spring does not like it - </p>
  
  <pre><code>public class CommonService&lt;Fruit&gt;{
    @Autowired
    BaseRepository&lt;Fruit&gt; repository;
  }
  </code></pre>
  
  <p>it gives the error - </p>
  
  <blockquote>
    <p>org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.data.jpa.repository.JpaRepository] is defined: expected single matching bean but found 4</p>
  </blockquote>
  
  <p>One way that I can make it work (what I have currently done), is to pass the Entity to every method in the CommonService, which then uses the appropriate repository based on the entity type passed (using instanceof) - clearly this is not the most efficient way - </p>
  
  <pre><code>    switch (determineEntityType(incomingFruit)) {
          case APPLE:
              localFruit = appleRepository.findByIdAndCountryId(id, countryId);
              break;
          case ORANGE:
              localFruit = orangeRepository.findByIdAndCountryId(id, countryId);
              break;
          case BANANA:
              localFruit = bananaRepository.findByIdAndCountryId(id, countryId);
              break;
          case GRAPE:
              localFruit = grapeRepository.findByIdAndCountryId(id, countryId);
              break;
          default:
              /* throwing UnrecognizedFruitException */
      }
  </code></pre>
  
  <p>There are couple other similar questions on SO, but no answers / solutions so far - e.g. </p>
  
  <ol>
  <li><a href="https://stackoverflow.com/questions/31154382/spring-data-autowire-jparepository-generic-type">Spring data: Autowire JpaRepository (Generic type)</a></li>
  <li><a href="https://stackoverflow.com/questions/7658899/how-to-save-simple-crud-codes-in-a-service-just-like-genericdao-jparepository">how to save simple CRUD codes in a service, just like GenericDao/JpaRepository?</a></li>
  </ol>
  
  <p>Thank you for your help !</p>