title: Generic parameter for JpaRepository save method
body: <h2>Problem:</h2>
  
  <hr>
  
  <p>My Domain-Layer has a couple of ValueClasses all extending a AbstractValue class and this AbstractValue class extends a BaseEntity class.</p>
  
  <pre><code>public abstract class AbstractValue extends BaseEntity{}
  
  public class Value extends AbstractValue{}
  </code></pre>
  
  <p>In my Repository-Layer I'm working with Spring-Data-Repositories which will automatically be implemented. As in the domain layer there is some sort of AbstractValueRepository extending the CrudRepository interface and a few ValueRepositories extending the AbstractValueRepository.</p>
  
  <pre><code>@NoRepositoryBean
  public interface AbstractValueRepository&lt;T extends AbstractValue&gt; extends CrudRepository&lt;T, Long&gt; {}
  
  public interface ValueRepository extends AbstractValueRepository&lt;Value&gt;
  </code></pre>
  
  <p>In my Business-Layer I have one ValueService interface with a few methods and and implementation class, as well as an enum listing all the available ValueRepositories.</p>
  
  <pre><code>public enum ValueType {
  
      VALUE(ValueRepository.class),
      VALUE1(Value1Repository.class),
      VALUE2(Value2Repository.class),
      VALUE3(Value3Repository.class),
      ;
  
      private final Class&lt;? extends AbstractValueRepository&lt;? extends AbstractValue&gt;&gt;     repository;
  
      ValueType(final Class&lt;? extends AbstractValueRepository&lt;? extends AbstractValue&gt;&gt; repository) {
          this.repository = repository;
      }
  
      public Class&lt;? extends AbstractValueRepository&lt;? extends AbstractValue&gt;&gt; getRepository() {
          return repository;
      }
  }
  
  @Service
  public class ValueServiceImpl implements ValueService {
  
      @Autowired 
      private ApplicationContext applicationContext;
  
      @Autowired
      private ApplicatieRepository applicatieRepository;
  
      @Override
      public &lt;S extends AbstractValueType&gt; S updateValueForType(ValueType type, S value) {
          return applicationContext.getBean(type.getRepository()).save(value);
      }
  
      @Override
      public &lt;S extends AbstractValueType&gt; S createValueForType(ValueType type, S value) {
          return applicationContext.getBean(type.getRepository()).save(value);
      }
  }
  </code></pre>
  
  <p>Now the problem occurs that the save method for a value of type S extends AbstractValueType does not exists. The CrudRepository does this.</p>
  
  <pre><code>@NoRepositoryBean
  public interface CrudRepository&lt;T, ID extends Serializable&gt; extends Repository&lt;T, ID&gt; {
      &lt;S extends T&gt; S save(S var1);
  }
  </code></pre>
  
  <p>So basically the save method expects a value of a type extended from Type given in the repository which in case of ValueRepository is Value (which extends AbstractValue) but in the Service the save method uses a Type S extends AbstractValue. I have been looking for fixes to make it work and I think it kinda needs to be something like this (although this syntax is wrong)</p>
  
  <pre><code>@Override
  public &lt;S extends AbstractValueType&gt; S updateValueForType(ValueType type, T &lt;? extends S&gt; value) {
      return applicationContext.getBean(type.getRepository()).save(value);
  }
  </code></pre>
  
  <p>Even though this is not correct I feel as if this is the direction I need to search in. Any help would be appreciated, Many thanks.</p>