title: JPA criteria predicate query combining Integer and String arguments
body: <p>I'm using JPA (EclipseLink flavor), framework JSF 2.0, querying a MySQL contacts table containing 4 fields: </p>
  
  <pre><code>contactId(int Pk), firstName (String), surname(String), countryId(int Foreign key)
  </code></pre>
  
  <p>The below code works fine if only using string arguments so that the user can enter as many or as few search strings as required (ie: if the search boxes are left blank, this is equivalent to select * and the entire dataset is returned). </p>
  
  <p>The problem is in combining an integer argument (countryId) which is the foreign key that adds countries to the search criteria. After some research, I'm still having trouble understanding the right way to do this. </p>
  
  <p>Does the integer need to be converted to a string representation within the searchContacts method? I gathered that JPA Criteria API provides typcasting but not type conversion methods? If so, What is the best way to include an integer in the below method and pass this integer into the predicateArray? </p>
  
  <p>Thanks in advance!</p>
  
  <pre><code>public ListDataModel&lt;Contacts&gt; searchContacts(String firstname, String surName, int countryId) {
  
      CriteriaBuilder cb = em.getCriteriaBuilder();
      CriteriaQuery&lt;Contacts&gt; query = cb.createQuery(Contacts.class);
      Root&lt;Contacts&gt; cont = query.from(Contacts.class);
      query.select(cont);
  
      List&lt;Predicate&gt; predicateList = new ArrayList&lt;Predicate&gt;();
      Predicate firstnamePredicate, surnamePredicate, countryPredicate;
  
  
      if ((firstname != null) &amp;&amp; (!(firstname.isEmpty()))) {
          firstnamePredicate = cb.like(cb.upper(cont.&lt;String&gt;get("firstname")), "%" + firstname.toUpperCase() + "%");
          predicateList.add(firstnamePredicate);
      }
  
      if ((surName != null) &amp;&amp; (!(surName.isEmpty()))) {
          surnamePredicate = cb.like(cb.upper(cont.&lt;String&gt;get("surname")), "%" + surName.toUpperCase() + "%");
          predicateList.add(surnamePredicate);
      }
  // here is where I am stuck and trying the solution suggested     by     meskobalazs, except I changed null to 0 since countryId is an integer
      if (countryId != 0) {
      countryPredicate = cb.equal(cont.&lt;Integer&gt;get("countryid"), countryId);
      predicateList.add(countryPredicate);
     }
      Predicate[] predicateArray = new Predicate[predicateList.size()];
      predicateList.toArray(predicateArray);
      query.where(predicateArray);
      ListDataModel&lt;Contacts&gt; contactList = new ListDataModel&lt;Contacts&gt;(em.createQuery(query).getResultList());
  
      return contactList;
  }
  </code></pre>
  
  <p>}</p>
  
  <p>The above caused the following EJB Exception:</p>
  
  <pre><code>Caused by: Exception [EclipseLink-6078] (Eclipse Persistence Services -     2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.QueryException
  Exception Description: The class of the argument for the object comparison is incorrect. 
  Expression: [
  Base com.manaar.domains.Contacts] 
  Mapping: [org.eclipse.persistence.mappings.ManyToOneMapping[countryid]] 
  Argument: [1]
  Query: ReadAllQuery(referenceClass=Contacts )
  at    org.eclipse.persistence.exceptions.QueryException.incorrectClassForObjectComparison(QueryException.java:595)
  at org.eclipse.persistence.mappings.OneToOneMapping.buildObjectJoinExpression(OneToOneMapping.java:287)
  at org.eclipse.persistence.internal.expressions.RelationExpression.normalize(RelationExpression.java:803)
  </code></pre>
  
  <p>The countryid is an integer with a manyToOne mapping in the contacts entity to the country entity. The contacts entity is: </p>
  
  <pre><code>@Entity
  @Table(name = "contacts")
  @XmlRootElement
  public class Contacts implements Serializable {
  private static final long serialVersionUID = 1L;
  @Id
  @Basic(optional = false)
  @NotNull
  @Column(name = "CONTACTSID")
  private Integer contactsid;
  @JoinColumn(name = "countryid", referencedColumnName = "COUNTRYID")
  @ManyToOne
  private Country countryid;
  </code></pre>
  
  <p>The country entity is:</p>
  
  <pre><code>@Entity
  @Table(name = "country")
  @XmlRootElement
  
  public class Country implements Serializable {
  private static final long serialVersionUID = 1L;
  @Id
  @Basic(optional = false)
  @NotNull
  @Column(name = "COUNTRYID")
  private Integer countryid;
  @Size(max = 255)
  @Column(name = "COUNTRYNAME")
  private String countryname;
  .....
  </code></pre>