JPA 条件谓词查询结合 Integer 和 String 参数

JPA criteria predicate query combining Integer and String arguments

我正在使用 JPA(EclipseLink 风格),框架 JSF 2.0,查询包含 4 个字段的 MySQL 联系人表:

contactId(int Pk), firstName (String), surname(String), countryId(int Foreign key)

public ListDataModel<Contacts> searchContacts(String firstname, String surName, int countryId) {



  CriteriaBuilder cb = em.getCriteriaBuilder();

  CriteriaQuery<Contacts> query = cb.createQuery(Contacts.class);

  Root<Contacts> cont = query.from(Contacts.class);

  query.select(cont);



  List<Predicate> predicateList = new ArrayList<Predicate>();

  Predicate firstnamePredicate, surnamePredicate, countryPredicate;





  if ((firstname != null) && (!(firstname.isEmpty()))) {

    firstnamePredicate = cb.like(cb.upper(cont.<String>get("firstname")),"%" + firstname.toUpperCase() +"%");

    predicateList.add(firstnamePredicate);

  }



  if ((surName != null) && (!(surName.isEmpty()))) {

    surnamePredicate = cb.like(cb.upper(cont.<String>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.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

 }

  Predicate[] predicateArray = new Predicate[predicateList.size()];

  predicateList.toArray(predicateArray);

  query.where(predicateArray);

  ListDataModel<Contacts> contactList = new ListDataModel<Contacts>(em.createQuery(query).getResultList());



  return contactList;

}
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)
@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;
@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;

.....
if (countryId != null) {

  countryPredicate = cb.equal(cont.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

}
cont.<MyType>get("typeName")
cont.get(_MyType.typeName)
@Column(name ="countryid", insertable = false, updatable = false)

private Integer countryId;



@JoinColumn(name ="countryid", referencedColumnName ="countryid")

@ManyToOne

private Country country;

if (countryId != null) {

  Join<Contacts, Country> country = cont.join("countryid");

  countryPredicate = cb.equal(country.<Integer>get("countryId"), countryId);

  predicateList.add(countryPredicate);

}

如果仅使用字符串参数,则以下代码可以正常工作,以便用户可以根据需要输入尽可能多或尽可能少的搜索字符串(即:如果搜索框留空,则相当于选择 * 并且整个数据集是回)。

问题在于组合一个整数参数 (countryId),它是将国家添加到搜索条件的外键。经过一些研究,我仍然无法理解正确的方法来做到这一点。

是否需要在 searchContacts 方法中将整数转换为字符串表示形式?我收集到 JPA Criteria API 提供类型转换但不提供类型转换方法?如果是这样,在下面的方法中包含一个整数并将这个整数传递给 predicateArray 的最佳方法是什么?

提前致谢!

contactId(int Pk), firstName (String), surname(String), countryId(int Foreign key)

public ListDataModel<Contacts> searchContacts(String firstname, String surName, int countryId) {



  CriteriaBuilder cb = em.getCriteriaBuilder();

  CriteriaQuery<Contacts> query = cb.createQuery(Contacts.class);

  Root<Contacts> cont = query.from(Contacts.class);

  query.select(cont);



  List<Predicate> predicateList = new ArrayList<Predicate>();

  Predicate firstnamePredicate, surnamePredicate, countryPredicate;





  if ((firstname != null) && (!(firstname.isEmpty()))) {

    firstnamePredicate = cb.like(cb.upper(cont.<String>get("firstname")),"%" + firstname.toUpperCase() +"%");

    predicateList.add(firstnamePredicate);

  }



  if ((surName != null) && (!(surName.isEmpty()))) {

    surnamePredicate = cb.like(cb.upper(cont.<String>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.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

 }

  Predicate[] predicateArray = new Predicate[predicateList.size()];

  predicateList.toArray(predicateArray);

  query.where(predicateArray);

  ListDataModel<Contacts> contactList = new ListDataModel<Contacts>(em.createQuery(query).getResultList());



  return contactList;

}
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)
@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;
@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;

.....
if (countryId != null) {

  countryPredicate = cb.equal(cont.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

}
cont.<MyType>get("typeName")
cont.get(_MyType.typeName)
@Column(name ="countryid", insertable = false, updatable = false)

private Integer countryId;



@JoinColumn(name ="countryid", referencedColumnName ="countryid")

@ManyToOne

private Country country;

if (countryId != null) {

  Join<Contacts, Country> country = cont.join("countryid");

  countryPredicate = cb.equal(country.<Integer>get("countryId"), countryId);

  predicateList.add(countryPredicate);

}

}

上述导致以下 EJB 异常:

contactId(int Pk), firstName (String), surname(String), countryId(int Foreign key)

public ListDataModel<Contacts> searchContacts(String firstname, String surName, int countryId) {



  CriteriaBuilder cb = em.getCriteriaBuilder();

  CriteriaQuery<Contacts> query = cb.createQuery(Contacts.class);

  Root<Contacts> cont = query.from(Contacts.class);

  query.select(cont);



  List<Predicate> predicateList = new ArrayList<Predicate>();

  Predicate firstnamePredicate, surnamePredicate, countryPredicate;





  if ((firstname != null) && (!(firstname.isEmpty()))) {

    firstnamePredicate = cb.like(cb.upper(cont.<String>get("firstname")),"%" + firstname.toUpperCase() +"%");

    predicateList.add(firstnamePredicate);

  }



  if ((surName != null) && (!(surName.isEmpty()))) {

    surnamePredicate = cb.like(cb.upper(cont.<String>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.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

 }

  Predicate[] predicateArray = new Predicate[predicateList.size()];

  predicateList.toArray(predicateArray);

  query.where(predicateArray);

  ListDataModel<Contacts> contactList = new ListDataModel<Contacts>(em.createQuery(query).getResultList());



  return contactList;

}
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)
@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;
@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;

.....
if (countryId != null) {

  countryPredicate = cb.equal(cont.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

}
cont.<MyType>get("typeName")
cont.get(_MyType.typeName)
@Column(name ="countryid", insertable = false, updatable = false)

private Integer countryId;



@JoinColumn(name ="countryid", referencedColumnName ="countryid")

@ManyToOne

private Country country;

if (countryId != null) {

  Join<Contacts, Country> country = cont.join("countryid");

  countryPredicate = cb.equal(country.<Integer>get("countryId"), countryId);

  predicateList.add(countryPredicate);

}

countryid 是一个整数,在联系人实体到国家实体中具有 manyToOne 映射。联系人实体是:

contactId(int Pk), firstName (String), surname(String), countryId(int Foreign key)

public ListDataModel<Contacts> searchContacts(String firstname, String surName, int countryId) {



  CriteriaBuilder cb = em.getCriteriaBuilder();

  CriteriaQuery<Contacts> query = cb.createQuery(Contacts.class);

  Root<Contacts> cont = query.from(Contacts.class);

  query.select(cont);



  List<Predicate> predicateList = new ArrayList<Predicate>();

  Predicate firstnamePredicate, surnamePredicate, countryPredicate;





  if ((firstname != null) && (!(firstname.isEmpty()))) {

    firstnamePredicate = cb.like(cb.upper(cont.<String>get("firstname")),"%" + firstname.toUpperCase() +"%");

    predicateList.add(firstnamePredicate);

  }



  if ((surName != null) && (!(surName.isEmpty()))) {

    surnamePredicate = cb.like(cb.upper(cont.<String>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.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

 }

  Predicate[] predicateArray = new Predicate[predicateList.size()];

  predicateList.toArray(predicateArray);

  query.where(predicateArray);

  ListDataModel<Contacts> contactList = new ListDataModel<Contacts>(em.createQuery(query).getResultList());



  return contactList;

}
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)
@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;
@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;

.....
if (countryId != null) {

  countryPredicate = cb.equal(cont.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

}
cont.<MyType>get("typeName")
cont.get(_MyType.typeName)
@Column(name ="countryid", insertable = false, updatable = false)

private Integer countryId;



@JoinColumn(name ="countryid", referencedColumnName ="countryid")

@ManyToOne

private Country country;

if (countryId != null) {

  Join<Contacts, Country> country = cont.join("countryid");

  countryPredicate = cb.equal(country.<Integer>get("countryId"), countryId);

  predicateList.add(countryPredicate);

}

国家实体是:

contactId(int Pk), firstName (String), surname(String), countryId(int Foreign key)

public ListDataModel<Contacts> searchContacts(String firstname, String surName, int countryId) {



  CriteriaBuilder cb = em.getCriteriaBuilder();

  CriteriaQuery<Contacts> query = cb.createQuery(Contacts.class);

  Root<Contacts> cont = query.from(Contacts.class);

  query.select(cont);



  List<Predicate> predicateList = new ArrayList<Predicate>();

  Predicate firstnamePredicate, surnamePredicate, countryPredicate;





  if ((firstname != null) && (!(firstname.isEmpty()))) {

    firstnamePredicate = cb.like(cb.upper(cont.<String>get("firstname")),"%" + firstname.toUpperCase() +"%");

    predicateList.add(firstnamePredicate);

  }



  if ((surName != null) && (!(surName.isEmpty()))) {

    surnamePredicate = cb.like(cb.upper(cont.<String>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.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

 }

  Predicate[] predicateArray = new Predicate[predicateList.size()];

  predicateList.toArray(predicateArray);

  query.where(predicateArray);

  ListDataModel<Contacts> contactList = new ListDataModel<Contacts>(em.createQuery(query).getResultList());



  return contactList;

}
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)
@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;
@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;

.....
if (countryId != null) {

  countryPredicate = cb.equal(cont.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

}
cont.<MyType>get("typeName")
cont.get(_MyType.typeName)
@Column(name ="countryid", insertable = false, updatable = false)

private Integer countryId;



@JoinColumn(name ="countryid", referencedColumnName ="countryid")

@ManyToOne

private Country country;

if (countryId != null) {

  Join<Contacts, Country> country = cont.join("countryid");

  countryPredicate = cb.equal(country.<Integer>get("countryId"), countryId);

  predicateList.add(countryPredicate);

}

谓词的解决方案

Predicate 类没有类型(通用),因此您不需要以任何不同的方式收集不同的谓词。这应该可以正常工作:

contactId(int Pk), firstName (String), surname(String), countryId(int Foreign key)

public ListDataModel<Contacts> searchContacts(String firstname, String surName, int countryId) {



  CriteriaBuilder cb = em.getCriteriaBuilder();

  CriteriaQuery<Contacts> query = cb.createQuery(Contacts.class);

  Root<Contacts> cont = query.from(Contacts.class);

  query.select(cont);



  List<Predicate> predicateList = new ArrayList<Predicate>();

  Predicate firstnamePredicate, surnamePredicate, countryPredicate;





  if ((firstname != null) && (!(firstname.isEmpty()))) {

    firstnamePredicate = cb.like(cb.upper(cont.<String>get("firstname")),"%" + firstname.toUpperCase() +"%");

    predicateList.add(firstnamePredicate);

  }



  if ((surName != null) && (!(surName.isEmpty()))) {

    surnamePredicate = cb.like(cb.upper(cont.<String>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.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

 }

  Predicate[] predicateArray = new Predicate[predicateList.size()];

  predicateList.toArray(predicateArray);

  query.where(predicateArray);

  ListDataModel<Contacts> contactList = new ListDataModel<Contacts>(em.createQuery(query).getResultList());



  return contactList;

}
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)
@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;
@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;

.....
if (countryId != null) {

  countryPredicate = cb.equal(cont.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

}
cont.<MyType>get("typeName")
cont.get(_MyType.typeName)
@Column(name ="countryid", insertable = false, updatable = false)

private Integer countryId;



@JoinColumn(name ="countryid", referencedColumnName ="countryid")

@ManyToOne

private Country country;

if (countryId != null) {

  Join<Contacts, Country> country = cont.join("countryid");

  countryPredicate = cb.equal(country.<Integer>get("countryId"), countryId);

  predicateList.add(countryPredicate);

}

JPA 规范元模型

这只是一个建议,但您也可以考虑为您的实体构建规范元模型(例如使用 Apache Dali),这样您就可以以类型安全的方式 get 您的字段。

代替

contactId(int Pk), firstName (String), surname(String), countryId(int Foreign key)

public ListDataModel<Contacts> searchContacts(String firstname, String surName, int countryId) {



  CriteriaBuilder cb = em.getCriteriaBuilder();

  CriteriaQuery<Contacts> query = cb.createQuery(Contacts.class);

  Root<Contacts> cont = query.from(Contacts.class);

  query.select(cont);



  List<Predicate> predicateList = new ArrayList<Predicate>();

  Predicate firstnamePredicate, surnamePredicate, countryPredicate;





  if ((firstname != null) && (!(firstname.isEmpty()))) {

    firstnamePredicate = cb.like(cb.upper(cont.<String>get("firstname")),"%" + firstname.toUpperCase() +"%");

    predicateList.add(firstnamePredicate);

  }



  if ((surName != null) && (!(surName.isEmpty()))) {

    surnamePredicate = cb.like(cb.upper(cont.<String>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.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

 }

  Predicate[] predicateArray = new Predicate[predicateList.size()];

  predicateList.toArray(predicateArray);

  query.where(predicateArray);

  ListDataModel<Contacts> contactList = new ListDataModel<Contacts>(em.createQuery(query).getResultList());



  return contactList;

}
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)
@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;
@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;

.....
if (countryId != null) {

  countryPredicate = cb.equal(cont.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

}
cont.<MyType>get("typeName")
cont.get(_MyType.typeName)
@Column(name ="countryid", insertable = false, updatable = false)

private Integer countryId;



@JoinColumn(name ="countryid", referencedColumnName ="countryid")

@ManyToOne

private Country country;

if (countryId != null) {

  Join<Contacts, Country> country = cont.join("countryid");

  countryPredicate = cb.equal(country.<Integer>get("countryId"), countryId);

  predicateList.add(countryPredicate);

}

你可以写:

contactId(int Pk), firstName (String), surname(String), countryId(int Foreign key)

public ListDataModel<Contacts> searchContacts(String firstname, String surName, int countryId) {



  CriteriaBuilder cb = em.getCriteriaBuilder();

  CriteriaQuery<Contacts> query = cb.createQuery(Contacts.class);

  Root<Contacts> cont = query.from(Contacts.class);

  query.select(cont);



  List<Predicate> predicateList = new ArrayList<Predicate>();

  Predicate firstnamePredicate, surnamePredicate, countryPredicate;





  if ((firstname != null) && (!(firstname.isEmpty()))) {

    firstnamePredicate = cb.like(cb.upper(cont.<String>get("firstname")),"%" + firstname.toUpperCase() +"%");

    predicateList.add(firstnamePredicate);

  }



  if ((surName != null) && (!(surName.isEmpty()))) {

    surnamePredicate = cb.like(cb.upper(cont.<String>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.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

 }

  Predicate[] predicateArray = new Predicate[predicateList.size()];

  predicateList.toArray(predicateArray);

  query.where(predicateArray);

  ListDataModel<Contacts> contactList = new ListDataModel<Contacts>(em.createQuery(query).getResultList());



  return contactList;

}
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)
@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;
@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;

.....
if (countryId != null) {

  countryPredicate = cb.equal(cont.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

}
cont.<MyType>get("typeName")
cont.get(_MyType.typeName)
@Column(name ="countryid", insertable = false, updatable = false)

private Integer countryId;



@JoinColumn(name ="countryid", referencedColumnName ="countryid")

@ManyToOne

private Country country;

if (countryId != null) {

  Join<Contacts, Country> country = cont.join("countryid");

  countryPredicate = cb.equal(country.<Integer>get("countryId"), countryId);

  predicateList.add(countryPredicate);

}

如果您正在重构实体,这尤其有用,因为您可能会忘记更新字符串,但您不能忘记更新元模型,因为代码甚至无法编译。

更新

我遗漏了一些与您的实体有关的设计问题。有两种可能的解决方案。

创建一个新的实体字段

第一个是在 Contacts 中创建一个实际的 Integer 字段并将其映射到与 countryId 相同的字段。

所以你应该将 Country 字段重命名为 Country,并创建一个新字段。

contactId(int Pk), firstName (String), surname(String), countryId(int Foreign key)

public ListDataModel<Contacts> searchContacts(String firstname, String surName, int countryId) {



  CriteriaBuilder cb = em.getCriteriaBuilder();

  CriteriaQuery<Contacts> query = cb.createQuery(Contacts.class);

  Root<Contacts> cont = query.from(Contacts.class);

  query.select(cont);



  List<Predicate> predicateList = new ArrayList<Predicate>();

  Predicate firstnamePredicate, surnamePredicate, countryPredicate;





  if ((firstname != null) && (!(firstname.isEmpty()))) {

    firstnamePredicate = cb.like(cb.upper(cont.<String>get("firstname")),"%" + firstname.toUpperCase() +"%");

    predicateList.add(firstnamePredicate);

  }



  if ((surName != null) && (!(surName.isEmpty()))) {

    surnamePredicate = cb.like(cb.upper(cont.<String>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.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

 }

  Predicate[] predicateArray = new Predicate[predicateList.size()];

  predicateList.toArray(predicateArray);

  query.where(predicateArray);

  ListDataModel<Contacts> contactList = new ListDataModel<Contacts>(em.createQuery(query).getResultList());



  return contactList;

}
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)
@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;
@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;

.....
if (countryId != null) {

  countryPredicate = cb.equal(cont.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

}
cont.<MyType>get("typeName")
cont.get(_MyType.typeName)
@Column(name ="countryid", insertable = false, updatable = false)

private Integer countryId;



@JoinColumn(name ="countryid", referencedColumnName ="countryid")

@ManyToOne

private Country country;

if (countryId != null) {

  Join<Contacts, Country> country = cont.join("countryid");

  countryPredicate = cb.equal(country.<Integer>get("countryId"), countryId);

  predicateList.add(countryPredicate);

}

完成此操作后,您就可以使用我原来的解决方案了。

使用连接

第二种解决方案是在查询中使用 Join

contactId(int Pk), firstName (String), surname(String), countryId(int Foreign key)

public ListDataModel<Contacts> searchContacts(String firstname, String surName, int countryId) {



  CriteriaBuilder cb = em.getCriteriaBuilder();

  CriteriaQuery<Contacts> query = cb.createQuery(Contacts.class);

  Root<Contacts> cont = query.from(Contacts.class);

  query.select(cont);



  List<Predicate> predicateList = new ArrayList<Predicate>();

  Predicate firstnamePredicate, surnamePredicate, countryPredicate;





  if ((firstname != null) && (!(firstname.isEmpty()))) {

    firstnamePredicate = cb.like(cb.upper(cont.<String>get("firstname")),"%" + firstname.toUpperCase() +"%");

    predicateList.add(firstnamePredicate);

  }



  if ((surName != null) && (!(surName.isEmpty()))) {

    surnamePredicate = cb.like(cb.upper(cont.<String>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.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

 }

  Predicate[] predicateArray = new Predicate[predicateList.size()];

  predicateList.toArray(predicateArray);

  query.where(predicateArray);

  ListDataModel<Contacts> contactList = new ListDataModel<Contacts>(em.createQuery(query).getResultList());



  return contactList;

}
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)
@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;
@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;

.....
if (countryId != null) {

  countryPredicate = cb.equal(cont.<Integer>get("countryid"), countryId);

  predicateList.add(countryPredicate);

}
cont.<MyType>get("typeName")
cont.get(_MyType.typeName)
@Column(name ="countryid", insertable = false, updatable = false)

private Integer countryId;



@JoinColumn(name ="countryid", referencedColumnName ="countryid")

@ManyToOne

private Country country;

if (countryId != null) {

  Join<Contacts, Country> country = cont.join("countryid");

  countryPredicate = cb.equal(country.<Integer>get("countryId"), countryId);

  predicateList.add(countryPredicate);

}

相关推荐

  • Spring部署设置openshift

    Springdeploymentsettingsopenshift我有一个问题让我抓狂了三天。我根据OpenShift帐户上的教程部署了spring-eap6-quickstart代码。我已配置调试选项,并且已将Eclipse工作区与OpehShift服务器同步-服务器上的一切工作正常,但在Eclipse中出现无法消除的错误。我有这个错误:cvc-complex-type.2.4.a:Invali…
    2025-04-161
  • 检查Java中正则表达式中模式的第n次出现

    CheckfornthoccurrenceofpatterninregularexpressioninJava本问题已经有最佳答案,请猛点这里访问。我想使用Java正则表达式检查输入字符串中特定模式的第n次出现。你能建议怎么做吗?这应该可以工作:MatchResultfindNthOccurance(intn,Patternp,CharSequencesrc){Matcherm=p.matcher…
    2025-04-161
  • 如何让 JTable 停留在已编辑的单元格上

    HowtohaveJTablestayingontheeditedcell如果有人编辑JTable的单元格内容并按Enter,则内容会被修改并且表格选择会移动到下一行。是否可以禁止JTable在单元格编辑后转到下一行?原因是我的程序使用ListSelectionListener在单元格选择上同步了其他一些小部件,并且我不想在编辑当前单元格后选择下一行。Enter的默认绑定是名为selectNext…
    2025-04-161
  • Weblogic 12c 部署

    Weblogic12cdeploy我正在尝试将我的应用程序从Tomcat迁移到Weblogic12.2.1.3.0。我能够毫无错误地部署应用程序,但我遇到了与持久性提供程序相关的运行时错误。这是堆栈跟踪:javax.validation.ValidationException:CalltoTraversableResolver.isReachable()threwanexceptionatorg.…
    2025-04-161
  • Resteasy Content-Type 默认值

    ResteasyContent-Typedefaults我正在使用Resteasy编写一个可以返回JSON和XML的应用程序,但可以选择默认为XML。这是我的方法:@GET@Path("/content")@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})publicStringcontentListRequestXm…
    2025-04-161
  • 代码不会停止运行,在 Java 中

    thecodedoesn'tstoprunning,inJava我正在用Java解决项目Euler中的问题10,即"Thesumoftheprimesbelow10is2+3+5+7=17.Findthesumofalltheprimesbelowtwomillion."我的代码是packageprojecteuler_1;importjava.math.BigInteger;importjava…
    2025-04-161
  • Out of memory java heap space

    Outofmemoryjavaheapspace我正在尝试将大量文件从服务器发送到多个客户端。当我尝试发送大小为700mb的文件时,它显示了"OutOfMemoryjavaheapspace"错误。我正在使用Netbeans7.1.2版本。我还在属性中尝试了VMoption。但仍然发生同样的错误。我认为阅读整个文件存在一些问题。下面的代码最多可用于300mb。请给我一些建议。提前致谢publicc…
    2025-04-161
  • Log4j 记录到共享日志文件

    Log4jLoggingtoaSharedLogFile有没有办法将log4j日志记录事件写入也被其他应用程序写入的日志文件。其他应用程序可以是非Java应用程序。有什么缺点?锁定问题?格式化?Log4j有一个SocketAppender,它将向服务发送事件,您可以自己实现或使用与Log4j捆绑的简单实现。它还支持syslogd和Windows事件日志,这对于尝试将日志输出与来自非Java应用程序…
    2025-04-161