title: Spring-Data + QueryDSL + JDBC: how to map the query results to the domain objects?
body: <p>I am considering to use Spring-Data + QueryDSL + JDBC to replace (or enhance) the currently used MyBatis. <br/>
  My reasons are:</p>
  
  <ol>
  <li>Compile-time check of column names </li>
  <li>Compile-time check of SQL tatements and auto-completion from IDE </li>
  <li>Ability to write unit tests on Java Collections against the same code that will work against the actual DB, which is much simpler and faster than pre-populating a DB</li>
  <li>It is more concise than MyBatis – no need for a separate <em>XxxMapper.java</em> and <em>XxxMapper.xml</em> under the DAO layer</li>
  </ol>
  
  <p>Yet I see the following problems:</p>
  
  <ol>
  <li>There is no infrastructure for mapping the query results to domain objects. QueryDSL's <em>QBean</em> and <em>MappingProjection</em>, Spring's <em>BeanPropertyRowMapper</em> and Spring-Data's <em>OneToManyResultSetExtractor</em> seem to be too low level, see below.</li>
  <li>No out of the box session/transaction-level cache which comes for free in MyBatis</li>
  <li>No out of the box SQL statement and result logging which comes for free in MyBatis</li>
  </ol>
  
  <p>Since I am asking a single question let's concentrate on the mapping which I consider the most important problem.<br/>
  So my question is: <br/>
  <strong>Is there any convenient solution to map the QueryDSL's SQLQuery results to the domain object, similar to what MyBatis or JPA offer?</strong> That is, the mapping based on some simple configuration, be it XML, annotations, or simple Java?</p>
  
  <p>In particular, I am interested in the following:</p>
  
  <ol>
  <li>Mapping a column to a custom type, e.g. a String column to an <em>EmailAddress</em> Java object</li>
  <li>Mapping a group of columns to an embedded object, such as e.g. grouping <em>{first_name, last_name}</em> into a <em>FullName</em> Java object</li>
  <li>Supporting one-to-many relationship, such as being able to extract a <em>Customer</em> object(s) containing a list of <em>Addresses</em>.</li>
  </ol>
  
  <p>To summarize, I need an easy way to obtain one or many objects of the following '<em>Customer</em>' class from the following SQL query:</p>
  
  <pre><code>class Customer {
      EmailAddress emailAddress;
      FullName fullName;
      Set&lt;Address&gt; addresses;
      Set&lt;Comment&gt; selfDescription;
  }
  class EmailAddress {
      private String address;
      EmailAddress(String address) {this.address = address; }
  }
  class FullName {
      String firstName, lastName;
  }
  class Address {
      String street, town, country;
  }
  class Comment {
      LocalDateTime timeStamp;
      String content;
  }
  </code></pre>
  
  <p>Query:</p>
  
  <pre><code>query.from(qCustomer).
      leftJoin(qCustomer._addressCustomerRef, qAddress)).
      leftJoin(qCustomer._commentCustomerRed).
      getResults(
         qCustomer.email_address, qCustomer.first_name, qCustomer.last_name, 
         qAddress.street, qAddress.town, qAddress.country, 
         qComment.creation_time_stamp, qComment.content);
  </code></pre>
  
  <p><strong>The ideal solution for me would be to reuse the MyBatis mapping infrastructure.</strong> <br/>
  Another mapping solution or a custom one is also acceptable. <br/>
  Note: <br/>
  I could also accept "negative" answers if you show an alternative that:</p>
  
  <ol>
  <li>Possesses an ease of use and transparency comparable to that of MyBatis - you always know which SQL is executed by simply inspecting the code</li>
  <li>Allows full control over the executed SQL code, in particular, allows to easily write three DAO methods for retrieving 'Customer': without 'addresses' and 'selfDescription' information, just with 'addresses', and with all the fields</li>
  <li>Allows compile-time check of your SQL code</li>
  <li>Does not require hand-coding of mapping of every single domain class from SQL. </li>
  </ol>
  
  <p>The alternative should work well on the example above.</p>
  
  <p>Solutions already considered:</p>
  
  <ul>
  <li>MyBatis 'Builder' class (<a href="http://mybatis.github.io/mybatis-3/statement-builders.html" rel="nofollow">http://mybatis.github.io/mybatis-3/statement-builders.html</a>): not enough, since the column and table names are still Strings, so it violates requirement (3)</li>
  <li>Spring-data + JPA + QueryDSL: might be an option if you show how the requirements (1) and (2) can be satisfied and if no simpler solution will be provided </li>
  </ul>