title: When UserType represents Set of Objects in single line. How to query Hibernate custom UserType with like criteria?
body: <p>We are using custom Hibernate UserType to store a Set of Strings in a single line.</p>
  
  <p>When trying to Query this set with <strong>like</strong> criteria, using <em><strong>JPA CriteriaBuilder</strong></em> Hibernate throws <strong>IllegalArgumentException</strong></p>
  
  <p><code>Parameter value String did not match expected type java.util.Set</code></p>
  
  <p><strong>Is there a workaround for this?</strong></p>
  
  <p>Here is a UserType we are using:</p>
  
  <pre><code>public class SetStringType implements UserType, LiteralType&lt;Set&lt;String&gt;&gt; {
  
  final private static String SEPARATOR = "|";
  final private static String SEPARATOR_REGEXP = "\\|";
  
  @Override
  public int[] sqlTypes() {
      return new int[] { Types.VARCHAR };
  }
  
  @Override
  public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException,
          SQLException {
      HashSet&lt;String&gt; resultValues = new HashSet&lt;String&gt;();
  
      String value = rs.getString(names[0]);
      if (value == null)
          return resultValues;
  
      String[] values = value.split(SEPARATOR_REGEXP);
      resultValues.addAll(Arrays.asList(values));
      return resultValues;
  }
  
  @Override
  @SuppressWarnings("unchecked")
  public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException,
          SQLException {
      st.setString(index, StringUtils.collectionToDelimitedString((Collection&lt;String&gt;) value, SEPARATOR));
  }
  
  @Override
  @SuppressWarnings("rawtypes")
  public Class returnedClass() {
      return Set.class;
  }
  
  @Override
  public boolean equals(Object x, Object y) throws HibernateException {
      return ObjectUtils.equals(x, y);
  }
  
  @Override
  public int hashCode(Object x) throws HibernateException {
      assert x != null;
      return x.hashCode();
  }
  
  @Override
  @SuppressWarnings("unchecked")
  public Object deepCopy(Object value) throws HibernateException {
      if (value == null)
          return null;
  
      if (value instanceof HashSet)
          return ((HashSet&lt;String&gt;) value).clone();
  
      return new HashSet&lt;String&gt;((Collection&lt;String&gt;) value);
  }
  
  @Override
  public boolean isMutable() {
      return true;
  }
  
  @Override
  public Serializable disassemble(Object value) throws HibernateException {
      return (Serializable) deepCopy(value);
  }
  
  @Override
  public Object assemble(Serializable cached, Object owner) throws HibernateException {
      return deepCopy(cached);
  }
  
  @Override
  public Object replace(Object original, Object target, Object owner) throws HibernateException {
      return original;
  }
  
  @Override
  public String objectToSQLString(Set&lt;String&gt; value, Dialect dialect) throws Exception {
      return StringUtils.collectionToDelimitedString(value, SEPARATOR);
  }
  }
  </code></pre>