title: Spring Interface Projection with UUID
body: <p>I'm trying to use a <a href="https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections" rel="noreferrer">JPA Projection</a> (Spring v1.5.9.RELEASE) to return a custom type from a <code>JpaRepository</code> as follows (MCVE):</p>
  <pre><code>@Repository
  public interface TestRepository extends JpaRepository&lt;Void, Void&gt; {
  
      public interface TestValue {
          UUID getId();
          int getNum();
      }
  
      @Query(value = &quot;SELECT :id as id, 1 as num&quot;, nativeQuery = true)
      List&lt;TestValue&gt; getTestValues(@Param(&quot;id&quot;) UUID id);
      
  }
  </code></pre>
  <p>I would like to use the repository as follows:</p>
  <pre><code>List&lt;TestValue&gt; testValues = testRepository.getTestValues(UUID.randomUUID());
  int num = testValues.get(0).getNum(); // Returns 1 as expected
  UUID id = testValues.get(0).getId(); // ***Fails with an exception***
  </code></pre>
  <p>However, calling <code>getId()</code> fails with the following exception:</p>
  <pre><code>java.lang.IllegalArgumentException: Projection type must be an interface!
      at org.springframework.util.Assert.isTrue(Assert.java:92) ~[spring-core-4.3.13.RELEASE.jar:4.3.13.RELEASE]
      at org.springframework.data.projection.ProxyProjectionFactory.createProjection(ProxyProjectionFactory.java:110) ~[spring-data-commons-1.13.9.RELEASE.jar:?]
      at org.springframework.data.projection.SpelAwareProxyProjectionFactory.createProjection(SpelAwareProxyProjectionFactory.java:42) ~[spring-data-commons-1.13.9.RELEASE.jar:?]
      at org.springframework.data.projection.ProjectingMethodInterceptor.getProjection(ProjectingMethodInterceptor.java:126) ~[spring-data-commons-1.13.9.RELEASE.jar:?]
      at org.springframework.data.projection.ProjectingMethodInterceptor.invoke(ProjectingMethodInterceptor.java:76) ~[spring-data-commons-1.13.9.RELEASE.jar:?]
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE]
      at org.springframework.data.projection.ProxyProjectionFactory$TargetAwareMethodInterceptor.invoke(ProxyProjectionFactory.java:264) ~[spring-data-commons-1.13.9.RELEASE.jar:?]
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE]
      at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56) ~[spring-data-commons-1.13.9.RELEASE.jar:?]
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE]
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE]
      at com.sun.proxy.$Proxy199.getId(Unknown Source) ~[?:?]
      at ***my.company***
  </code></pre>
  <p>The returned <code>TestValue</code> proxy object stores the <code>id</code> attribute as a raw <code>byte</code> array. I would expect that the <code>ProjectingMethodInterceptor</code> eventually performs the actual type conversion to a <code>UUID</code> instance. Looking at the source code (<code>ProjectingMethodInterceptor.invoke(..):74</code>) it seems that it uses a <code>ConversionService</code> to do conversions. I tried the following:</p>
  <pre><code>@Configuration  
  public class MyApplicationConfig {
  
      @Bean
      public ConversionService conversionService() {
          DefaultConversionService service = new DefaultConversionService();
          service.addConverter(new UUIDConverter());
          return service;
      }
  }
  </code></pre>
  <p>The class <code>UUIDConverter</code> implements the interface <code>org.springframework.core.convert.converter.Converter&lt;byte[], UUID&gt;</code>. Unfortunately, <strong>this approach does not work</strong> as the used <code>ProjectingMethodInterceptor</code> is created via the <code>ProxyProjectingFactory</code> which bypasses the configured <code>ConversionService</code> and instantiates a <code>DefaultConversionService</code> (<code>ProxyProjectionFactory.ctor():65</code>).</p>
  <p>I also tried to add the annotation <code>@Convert(converter = UUIDConverter.class)</code> to the <code>getId()</code> declaration in <code>TestValue</code>, however, <strong>this approach does not work either</strong>.</p>
  <p>I obviously could change the return type of the <code>getId()</code> method to <code>byte[]</code> and perform the actual conversion to <code>UUID</code> in my application code, but this approach does not feel to be the right way to do it.</p>
  <blockquote>
  <p>Question 1:
  How are custom type conversions defined in <em>JPA Interface Projections</em>?</p>
  <p>Question 2:
  If this is not possible, what is the &quot;Spring-intended&quot; way to implement the above repository method with that exact method signature and underlying query.</p>
  </blockquote>