title: Generic Spring Data JPA Repository findAll
body: <p>Is there a way to make a generic Spring Data JPA repository handle correctly methods like <code>findAll()</code>? e.g. <code>AnimalRepository&lt;Dog&gt;.findAll</code> return only Dogs, instead of all animals? Or at least, how would be the best workaround at that?</p>
  
  <p>Say I have this:</p>
  
  <pre><code>@Entity
  @Inheritance(strategy = InheritanceType.JOINED)
  public abstract class Animal extends BaseEntity {
      ...
  }
  </code></pre>
  
  <hr>
  
  <pre><code>@Entity
  public class Dog extends Animal {
      ...
  }
  
  @Entity
  public class Capybara extends Animal {
      ...
  }
  </code></pre>
  
  <hr>
  
  <pre><code>public interface AnimalRepository&lt;T extends Animal&gt; extends JpaRepository&lt;T, Long&gt; {
  
  }
  </code></pre>
  
  <hr>
  
  <pre><code>@Service("animalService")
  public class AnimalServiceImpl&lt;T extends Animal&gt; implements AnimalService&lt;T&gt; {
  
      private final AnimalRepository&lt;T&gt; animalRepository;
  
      @Autowired
      public AnimalServiceImpl(AnimalRepository&lt;T&gt; aR) {
          this.animalRepository = aR;
      }
  
      @Override
      public void save(T animal) {
          animalRepository.save(animal);
      }
  
      @Override
      public List&lt;T&gt; findAll() {
          return animalRepository.findAll();
      }
  
      ...
  
  }
  </code></pre>
  
  <hr>
  
  <p>It works almost perfectly, saves each animal on its own table and so. The only problem is: the <code>findAll()</code> returns <em>BOTH</em> Capybaras and Dogs. This <a href="https://stackoverflow.com/a/19443031">answer</a> explains: </p>
  
  <blockquote>
    <p>This only works if the domain classes use single table inheritance. The only information about the domain class we can get at bootstrap time is that it will be Product objects. So for methods like findAll() and even findByName(…) the relevant queries will start with select p from Product p where…. This is due to the fact that the reflection lookup will never ever be able to produce Wine or Car unless you create a dedicated repository interface for it to capture the concrete type information.</p>
  </blockquote>
  
  <p>Ok, sadly the code gets a bit less clean having multiple repositories instead of only one. But I would still like to keep a single AnimalService class. This is the way I did:</p>
  
  <pre><code>@Service("animalService")
  public class AnimalServiceImpl&lt;T extends Animal&gt; implements AnimalService&lt;T&gt; {
  
      private final DogRepository dogRepository;
      private final CapybaraRepository capybaraRepository;
  
      @Autowired
      public AnimalServiceImpl(AnimalRepository&lt;T&gt; aR) {
          this.animalRepository = aR;
      }
  
      @Override
      public void save(T animal) {
          animalRepository.save(animal);
      }
  
      @Override
      public List&lt;T&gt; findAllDogs() {
          return dogRepository.findAll();
      }
  
      @Override
      public List&lt;T&gt; findAllCapybaras() {
          return capybaraRepository.findAll();
      }
  
      ...
  
  }
  </code></pre>
  
  <hr>
  
  <p>If the Repository really can't handle the <code>findAll()</code> according to the type <code>&lt;T&gt;</code>, what would be the cleanest way to have a single AnimalService? Surely there must be a better way than what I did, since it gets real ugly, really fast that way if you have more complexity in the service and more than a couple animals.</p>
  
  <hr>
  
  <p>EDIT: Given that Spring's DI considers <a href="https://stackoverflow.com/a/25650321/9180376"><code>AnimalRepository&lt;Dog&gt;</code> and <code>AnimalRepository&lt;Capybara&gt;</code> as being the same thing</a> (injecting the same Repository onto a Service that uses the Capybara one and another Service who uses the Dog one), I had to create a different Repository and Service for each of them (Option B of @ESala answer):</p>
  
  <pre><code>@NoRepositoryBean
  public interface AnimalRepository&lt;T extends Animal&gt; extends JpaRepository&lt;T, Long&gt; {
  }
  
  public interface DogRepository extends AnimalRepository&lt;Dog&gt; {   
  }
  
  public interface CapybaraRepository extends AnimalRepository&lt;Capybara&gt; {   
  }
  </code></pre>
  
  <hr>
  
  <pre><code>public abstract class AnimalService&lt;T extends Animal&gt; {
      private final AnimalRepository&lt;T&gt; animalRepository;
  
      AnimalService(AnimalRepository&lt;T&gt; repo) {
          this.animalRepository = repo;
      }
  
      public void salvar(T palavra) {
          animalRepository.save(palavra);
      }
  
      public List&lt;T&gt; findAll() {
          return animalRepository.findAll();
      }
  
  }
  
  @Service
  public class DogService extends AnimalService&lt;Dog&gt; {
  
      @Autowired
      public DogService(DogRepository repo) {
          super(repo);
      }
  }
  
  @Service
  public class CapybaraService extends AnimalService&lt;Capybara&gt; {
  
      @Autowired
      public CapybaraService(CapybaraRepository repo) {
          super(repo);
      }
  }
  </code></pre>
  
  <p>There's probably a better way, so I'll stay open to suggestions.</p>