简体   繁体   English

制定“表达”中的JPA标准

[英]Formulating a JPA Criteria 'in' Expression

I am requesting help in understanding how to formulate an 'in' condition using the javax.persistence.criteria package. 我需要帮助来了解如何使用javax.persistence.criteria包来制定“处于”状态。

I am creating a CriteriaQuery based up search criteria for a Contacts class. 我正在为联系人类创建基于CriteriaQuery的搜索条件。 A contact can belong to 0 to many contact types. 一个联系人可以属于0到许多联系人类型。 The search criteria can include a last name value, a contact type or both. 搜索条件可以包括姓氏值,联系人类型或两者。

When I try this: 当我尝试这个:

Expression<ContactType> param = criteriaBuilder.parameter(ContactType.class);           
Expression<List<ContactType>> contactTypes = fromContact.get("contactTypes");   
Predicate newPredicate = param.in(this.getContactType(), contactTypes);

I get: 我得到:

org.apache.openjpa.persistence.ArgumentException: Cannot execute query; declared parameters "ParameterExpression<ContactType>" were not given values.  You must supply a value for each of the following parameters, in the given order: [ParameterExpression<ContactType>]

I haven't been able to find a good example of how to do this. 我还没有找到一个很好的例子来说明如何做到这一点。 Any assitance and guidance is greatly apprecited. 非常感谢您的协助和指导。 Full code is below. 完整代码如下。

public CriteriaQuery<Contact> getSearchCriteriaQuery(EntityManager entityManager) {
    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaQuery<Contact> criteriaQuery = criteriaBuilder.createQuery(Contact.class);
    Root<Contact> fromContact = criteriaQuery.from(Contact.class);
    Predicate whereClause = criteriaBuilder.equal(fromContact.get("domain"), this.getDomain());

    if (!StringUtils.isEmpty(this.getLastName())) {
        Predicate newPredicate = criteriaBuilder.equal(fromContact.get("lastName"), this.getLastName());
        whereClause = criteriaBuilder.and(whereClause, newPredicate);
    }

    if (this.getContactType() != null) {
        Expression<ContactType> param = criteriaBuilder.parameter(ContactType.class);
        Expression<List<ContactType>> contactTypes = fromContact.get("contactTypes");
        Predicate newPredicate = param.in(this.getContactType(), contactTypes);
        whereClause = criteriaBuilder.and(whereClause, newPredicate);
    }

    return criteriaQuery.where(whereClause);
}

@Entity
@Table(name = "contact")
public class Contact implements Serializable {

    private static final long serialVersionUID = -2139645102271977237L;
    private Long id;
    private String firstName;
    private String lastName;
    private Domain domain;
    private List<ContactType> contactTypes;

    public Contact() {
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(unique = true, nullable = false)
    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "FIRST_NAME", length = 20)
    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    @Column(name = "LAST_NAME", length = 50)
    public String getLastName() {
        return this.lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    //bi-directional many-to-one association to Domain
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "DOMAIN")
    public Domain getDomain() {
        return this.domain;
    }

    public void setDomain(Domain domain) {
        this.domain = domain;
    }

    @ManyToMany
    @JoinTable(name = "CONTACT_CNTTYPE",
    joinColumns = {
        @JoinColumn(name = "CONTACT", referencedColumnName = "ID")},
    inverseJoinColumns = {
        @JoinColumn(name = "CONTACT_TYPE", referencedColumnName = "ID")})
    public List<ContactType> getContactTypes() {
        return this.contactTypes;
    }

    public void setContactTypes(List<ContactType> contactTypes) {
        this.contactTypes = contactTypes;
    }
}

You have to set the parameter value to the query when you list the results: 列出结果时,必须将参数值设置为查询:

TypedQuery<Entity> q = this.entityManager.createQuery(criteriaQuery);
q.setParameter(ContactType.class, yourContactTypeValueToFilter);
q.getResultList();

What 什么

criteriaBuilder.parameter(ContactType.class);

does, is to create a parameter in the query, that you need to bind later. 这样做是在查询中创建一个参数,您以后需要绑定它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM