title: Custom data types using EclipseLink and Querydsl
body: <p>I've created a custom data type for storing valid and normalized email addresses:</p>
  
  <pre><code>public class Email implements Serializable {
  
      private final String value;
  
      public Email(String emailAddress) {
          this.value = normalize(emailAddress);
          if (!isValid(value)) {
              throw new IllegalArgumentException("Email address format is not valid: " + value);
          }
      }
      ...
  }
  </code></pre>
  
  <p>And its correspondent JPA 2.1 converter for automatically storing to and retrieving from database:</p>
  
  <pre><code>@Converter(autoApply = true)
  public class EmailConverter implements AttributeConverter&lt;Email, String&gt; {
  
      @Override
      public String convertToDatabaseColumn(Email email) {
          return email == null ? null : email.toString();
      }
  
      @Override
      public Email convertToEntityAttribute(String email) {
          return email == null ? null : new Email(email);
      }
  
  }
  </code></pre>
  
  <p>Now, I can use it as a property of a person entity:</p>
  
  <pre><code>public class Person extends BaseEntity {
  
      private String name;
  
      private LocalDate birthDate;
  
      @QueryType(PropertyType.STRING)
      private Email email;
  
      ...
  }
  </code></pre>
  
  <p>And this works perfectly. But I have a problem when I try to find all persons by the starting of their email address using Querydsl. I've annotated email property with <code>@QueryType</code> as String. This way, Querydsl metamodel is created such ay I'm able to make a query (using <code>.startsWith()</code>) like this:</p>
  
  <pre><code>private static final QPerson person = QPerson.person;
  
  public List&lt;Person&gt; getEmailStartWith(String pattern) {
      pattern = Email.normalize(pattern);
      return new JPAQuery(getEntityManager())
          .from(person)
          .where(person.email.startsWith(pattern))
          .orderBy(person.email.asc())
          .list(person);
  }
  </code></pre>
  
  <p>But I get this exception when I run it:</p>
  
  <pre><code>java.lang.IllegalArgumentException: You have attempted to set a value of type class java.lang.String for parameter 1 with expected type of class xxx.Email from query string select person
  from Person person
  where person.email like ?1 escape '!'
  order by person.email asc.
  at org.eclipse.persistence.internal.jpa.QueryImpl.setParameterInternal(QueryImpl.java:932) ~[eclipselink-2.5.0.jar:2.5.0.v20130507-3faac2b]
  at org.eclipse.persistence.internal.jpa.QueryImpl.setParameterInternal(QueryImpl.java:906) ~[eclipselink-2.5.0.jar:2.5.0.v20130507-3faac2b]
  at org.eclipse.persistence.internal.jpa.EJBQueryImpl.setParameter(EJBQueryImpl.java:469) ~[eclipselink-2.5.0.jar:2.5.0.v20130507-3faac2b]
  at org.eclipse.persistence.internal.jpa.EJBQueryImpl.setParameter(EJBQueryImpl.java:1) ~[eclipselink-2.5.0.jar:2.5.0.v20130507-3faac2b]
  at com.mysema.query.jpa.impl.JPAUtil.setConstants(JPAUtil.java:44) ~[querydsl-jpa-3.2.1.jar:na]
  at com.mysema.query.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:130) ~[querydsl-jpa-3.2.1.jar:na]
  at com.mysema.query.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:97) ~[querydsl-jpa-3.2.1.jar:na]
  at com.mysema.query.jpa.impl.AbstractJPAQuery.list(AbstractJPAQuery.java:240) ~[querydsl-jpa-3.2.1.jar:na]
  ...
  </code></pre>
  
  <p>I can get the correct result using JPQL (and an inelegant trick, <code>concat</code>):</p>
  
  <pre><code>public List&lt;Person&gt; getEmailStartWith(String pattern) {
      pattern = Email.normalize(pattern);
      return getEntityManager()
          .createQuery("select p from Person p where p.email like concat(?1, '%')", Person.class)
          .setParameter(1, pattern)
          .getResultList();
  }
  </code></pre>
  
  <p>But of course I prefer Querydsl's type safety. Is possible to create this query using this library?</p>