title: Interface-Based Projections the getter method giving exception if the return type is java.sql.Timestamp
body: <p>I am using the spring boot strater 2.2.0.BUILD-SNAPSHOT with Spirng JPA. I need to used some complex SQL with group by some I am using the native query with interface based projection, I am able retrived all the fields but getting exception for the return type of <code>java.sql.Timestamp</code></p>
  
  <p>Example : 
  My Entity class</p>
  
  <pre><code>@Entity
  @Table(name = "trade")
  public class Trade {
  
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "trade_id")
  private long tradeId;
  
  @Column(name = "symbol")
  private String symbol;
  
  @Column(name = "exchange")
  private String exchange;
  
  @Column(name = "segment")
  private String segment;
  
  @Column(name = "clinet_trade_id")
  private long clientTradeId;
  
  @Column(name = "order_id")
  private long orderId;
  
  @Column(name = "price")
  private double price;
  
  @Column(name = "sell_type")
  private String tradeType;
  
  @Column(name = "quantity")
  private int quantity;
  
  @Column(name = "trade_date_time")
  private Timestamp tradeDateTime;
  }
  </code></pre>
  
  <p>The repository interface with the projection interface</p>
  
  <pre><code>@Repository("TradeRepository")
  public interface TradeRepository extends JpaRepository&lt;Trade, Long&gt; {
  
  
  // projection
  
  //https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections
  //Interface-based Projections
  //https://www.baeldung.com/spring-data-jpa-projections
  
  @Query(value = "select symbol,date(trade_date_time) as trade_date_time , sum(quantity) as quantity , sum(quantity*price) as price  from trade where sell_type ='sell' \n" + 
          "and trader_date &gt; ?1  and trader_date &lt; ?2 and user_id= ?3 " + 
          "group by symbol, date(trade_date_time) " + 
          "order by symbol, date(trade_date_time) ", nativeQuery = true)
   public List&lt;TradeView&gt; findByNativeQuery(Timestamp fromdate, Timestamp toDate, int userId);
  
  public static interface TradeView {
       public String getSymbol();
       public Timestamp getTradeDateTime();
       public int getQuantity();
       public double getPrice();
    }
  
  
  }
  </code></pre>
  
  <p>Here I am getting exception for the method <code>getTradeDateTime()</code> </p>
  
  <p>Excaption trace</p>
  
  <pre><code>java.lang.IllegalArgumentException: Projection type must be an interface!
  at org.springframework.util.Assert.isTrue(Assert.java:118)
  at org.springframework.data.projection.ProxyProjectionFactory.createProjection(ProxyProjectionFactory.java:100)
  at org.springframework.data.projection.SpelAwareProxyProjectionFactory.createProjection(SpelAwareProxyProjectionFactory.java:45)
  at org.springframework.data.projection.ProjectingMethodInterceptor.getProjection(ProjectingMethodInterceptor.java:131)
  at org.springframework.data.projection.ProjectingMethodInterceptor.invoke(ProjectingMethodInterceptor.java:80)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  at org.springframework.data.projection.ProxyProjectionFactory$TargetAwareMethodInterceptor.invoke(ProxyProjectionFactory.java:245)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
  at com.sun.proxy.$Proxy123.getTradeDateTime(Unknown Source)
  at org.cet.stockAnalysis.repository.TradeRepositoryTest.findAllSaleTradeByDateTest(TradeRepositoryTest.java:45)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
  at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
  at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
  at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
  at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
  at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
  at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
  at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
  at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
  at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
  at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
  at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
  at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
  at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
  </code></pre>
  
  <p>Can some one guide me what can be done, I have one solution is to change the DB column name to match with entity filed name, But I feel that is not right not, there must be some solution to this.</p>
  
  <p>Debug screen shot</p>
  
  <p><a href="https://i.stack.imgur.com/4vMKu.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/4vMKu.png" alt="enter image description here"></a></p>
  
  <p>Note :I am getting the exception when calling the getter method to read the value and at that time also it is going to to ProxyProjectionFactory line number 100 and at that time the type id java.sql.Timestamp and ginving the exception</p>
  
  <p>Scren shot</p>
  
  <p><a href="https://i.stack.imgur.com/BFIK6.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/BFIK6.png" alt="enter image description here"></a></p>
  
  <p>The Junit test class</p>
  
  <pre><code>@RunWith(SpringRunner.class)
  @DataJpaTest
  @AutoConfigureTestDatabase(replace=Replace.NONE)
  public class TradeRepositoryTest {
  
  @Autowired
  TradeRepository tradeRepository;
  
  @Test
  public void findAllSaleTradeByDateTest() {
      Date fromdate = new GregorianCalendar(2019, Calendar.FEBRUARY, 1).getTime();
      Date todate = new GregorianCalendar(2019, Calendar.MARCH, 31).getTime();
  
      Timestamp fromTimestamp= new Timestamp(fromdate.getTime());
      Timestamp toTimestamp= new Timestamp(todate.getTime());
  
      User user = new User();
      user.setId(1);
      List&lt;TradeView&gt; tradeviews =tradeRepository.findByNativeQuery(fromTimestamp, toTimestamp, 1);
      System.out.println(tradeviews.get(0).getSymbol());
      System.out.println(tradeviews.get(0).getPrice());
      System.out.println(tradeviews.get(0).getTradeDateTime() +" &gt;&gt;&gt;&gt;&gt;&gt; ");
      System.out.println(tradeviews.get(0).getQuantity());
  
  
      assertNotNull(tradeviews);
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Edit:</p>
  
  <p>With the suggestion of Simon, I change the interface return type to java.sql.Date form java.sql.Timestamp and it's work fine as my native sql return type was date, because of date funtion was used</p>
  
  <p>Hence chnaging the question title and details</p>