title: IllegalArgumentException thrown when a Path is created on a field with @Convert
body: <p>I am trying to build a criteria query and for each incoming filter a Predicate &quot;and&quot;-connected, e.g.</p>
  <pre><code>CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
  CriteriaQuery&lt;Long&gt; criteriaQuery = criteriaBuilder.createQuery(Long.class);
  Root&lt;T&gt; entityRoot = criteriaQuery.from(SampleEntity.class);
  // for each filterable field create a Predicate and included in as `criteriaQuery.where(...)`
  criteriaQuery.select(criteriaBuilder.count(entityRoot));
  entityManager.createQuery(criteriaQuery).setMaxResults(maxResult).getSingleResult();
  </code></pre>
  <p>For each such filter (see commented line in code sample above) first a Path is created.</p>
  <pre><code>Path&lt;?&gt; path = PathBuilder.buildFromFieldName(fieldName, rootEntity);
  </code></pre>
  <p>This would be the method:</p>
  <pre><code>public static &lt;T&gt; Path&lt;?&gt; buildFromFieldName(String fieldName, Root&lt;T&gt; entity) throws IllegalArgumentException {
      Path&lt;?&gt; path = entity;
      List&lt;String&gt; fieldNames = Arrays.asList(fieldName.split(&quot;\\.&quot;));
      for (String fieldNamePath : fieldNames) {
          path = path.get(fieldNamePath);
      }
      return path;
  }
  </code></pre>
  <p>Nested fields would come in e.g. named <code>myChild.mySet</code> given the following example.</p>
  <pre><code>@Entity
  @Table(name = &quot;T_SAMPLE&quot;)
  public class SampleEntity {
  
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private Long id;
  
      @Embedded
      private SampleChildEntity myChild;
  }
  
  @Embeddable
  public class SampleChildEntity {
  
      @Convert(converter = CommaSeparatedSetConverter.class, attributeName = &quot;mySet&quot;)
      private Set&lt;String&gt; mySet = new HashSet&lt;&gt;();
  
  }
  </code></pre>
  <p>Given that example the following exception is thrown when <code>criteriaBuilder.isMember(filterValue, path)</code> is called (&quot;filterValue&quot; would be the value to compare against, e.g. a search string).</p>
  <p>Reason: In method <code>buildFromFieldName</code> first the Path is created from the root entity (SampleEntity). It then has type <code>org.hibernate.query.criteria.internal.path.RootImpl</code>. When in the for loop the fieldNamePath <code>myChild</code> is processed the Path is recreated. It then is of type <code>org.hibernate.query.criteria.internal.path.SingularAttributePath</code> and that stays like that when the last fieldNamePath <code>mySet</code> is processed. Only when the <code>@Convert</code> is removed does the type change to a <code>org.hibernate.query.criteria.internal.path.PluralAttributePath</code> since it is a collection type.</p>
  <pre><code>java.lang.IllegalArgumentException: unknown collection expression type 
          [org.hibernate.query.criteria.internal.path.SingularAttributePath]
  
      at org.hibernate.query.criteria.internal.CriteriaBuilderImpl.isMember(CriteriaBuilderImpl.java:1324)
      [... stack trace contains further local classes ...]
  </code></pre>
  <p>So the reason is the <code>@Convert</code> on field <code>mySet</code> in the <code>SampleChildEntity</code>. Hibernate sees the type <code>Set&lt;String&gt;</code> but does not use a <code>PluralAttributePath</code> but <code>SingularAttributePath</code> which causes the problem. Without the <code>@Convert</code> it works but removing the converter is not an option.</p>
  <p>Is there any way this can work? Could the path be created differently?</p>