title: Query by a parent field but return a child class
body: <p>Is it possible to write a <code>Service</code> that provides a method that selects entities by a <strong>parent field</strong> but returns a <strong>child class</strong> that gets passed in by a parameter (or generic on the method)?</p>
  
  <p>Assuming the <code>Parent</code> has a String field called flag and two childs <code>Child1</code> and <code>Child2</code>, the <code>ParentService</code> should be usable like this:</p>
  
  <pre><code>Child1 child1 = parentService.findFlag(Child1.class, "de");
  Child2 child2 = parentService.findFlag(Child2.class, "de");
  </code></pre>
  
  <p>or</p>
  
  <pre><code>Child1 child1 = parentService.findFlag&lt;Child1&gt;("de");
  Child2 child2 = parentService.findFlag&lt;Child2&gt;("de");
  </code></pre>
  
  <p><strong>Detailed example:</strong></p>
  
  <p>Because it is quite hard to explain, this code should explain the scenario from above:</p>
  
  <p>Java Classes:</p>
  
  <ul>
  <li><code>Parameter</code> - abstract parent class having a common field for all childs
  <ul>
  <li><code>UiParameter</code> extends Parameter </li>
  <li><code>BatchParameter</code> extends Parameter</li>
  </ul></li>
  <li><code>ParameterService</code> - provides a <code>save(Parameter)</code> method that can be used for <code>UiParameter</code> and <code>BatchParameter</code> This method is used by other services to save all kinds of children</li>
  </ul>
  
  <p>Now it would be handy to add a <code>find(UiParameter.class, commonFieldSelector)</code> or <code>find(BatchParameter.class, commonFieldSelector)</code> method to the <code>ParameterService</code>.</p>
  
  <p>Currently there are 4 boilerblate classes (UiParameterService, UiParameterRepository, BatchParameterService, BatchParameterRepository) with just 1 method that looks almost similar.</p>
  
  <pre><code>@Data
  @EqualsAndHashCode(callSuper = true)
  @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
  @DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING)
  @DiscriminatorValue("PARAMETER")
  public abstract class Parameter extends AbstractEntity
  {
      // all children will share that
      @ManyToOne
      private Application commonField;
  }
  
  @Data
  @Entity
  @EqualsAndHashCode(callSuper = true)
  public class UiParameter extends Parameter
  {
      private String foo;
  }
  
  @Data
  @Entity
  @EqualsAndHashCode(callSuper = true)
  public class BatchParameter extends Parameter
  {
      private int size;
  }
  
  public interface ParameterRepository extends JpaRepository&lt;Parameter, Long&gt;
  {
      // That works great, but it returns all kind of children...
      List&lt;Parameter&gt; findByCommonField(final Application commonField);
  }
  
  @Service
  @RequiredArgsConstructor(onConstructor = @__(@Autowired))
  public class ParameterService
  {
      private final ParameterRepository parameterRepository;
  
      public ... findByCommonField...(...)
      {
          return ... magic ...;
      }
  }
  </code></pre>
  
  <p>The usual Service/Repository for all Childs approach leads in our case into boilerplate classes having just a <code>findFlag</code> method that gets copied from Child1 to ChildN.</p>
  
  <p>Changing the Domain (inheritance strategy) will be a problem.</p>
  
  <p><strong>Spring-Solution based on Maciejs answer:</strong></p>
  
  <pre><code>public interface ParameterRepository extends JpaRepository&lt;Parameter, Long&gt;
  {
      @Query("SELECT e FROM Parameter e WHERE TYPE(e) = ?1 AND e.commonField = ?2")
      &lt;E extends Parameter&gt; List&lt;E&gt; findByTopic(final Class&lt;E&gt; e, final Application commonField);
  }
  </code></pre>