JPA Criteria API并使用包含.in()的WHERE谓词进行查询

时间:2015-07-30 21:22:44

标签: jpa jpql criteria-api where-in

我想查询一下我的谓词是这样的:

CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
    CriteriaQuery<ProviderService> criteriaQuery = criteriaBuilder.createQuery(ProviderService.class);
    // FROM
    Root<ProviderService> providerService = criteriaQuery.from(ProviderService.class);
    // SELECT
    criteriaQuery.select(providerService);

// WHERE'S PREDICATE
    List<Predicate> predicates = new ArrayList<>();

    if(providers != null && providers.size() > 0) {

        predicates.add(providerService.get(ProviderService_.provider).in(providers));
    } 
criteriaQuery.where(predicates.toArray(new Predicate[] { }));

    TypedQuery<ProviderService> query = getEntityManager().createQuery(criteriaQuery);

    return query.getResultList();

我检查搜索提供商的任何提供商表单集合(列表)提供的提供商商品(ProviderService)。

我收到了类似的异常:

Caused by: java.lang.IllegalArgumentException: Unaware how to convert value [pl.salonea.entities.Provider@85eab3b6 : pl.salonea.entities.Provider] to requested type [java.lang.Long]
at org.hibernate.jpa.criteria.ValueHandlerFactory.unknownConversion(ValueHandlerFactory.java:258)
at org.hibernate.jpa.criteria.ValueHandlerFactory.access$000(ValueHandlerFactory.java:34)
at org.hibernate.jpa.criteria.ValueHandlerFactory$LongValueHandler.convert(ValueHandlerFactory.java:152)
at org.hibernate.jpa.criteria.ValueHandlerFactory$LongValueHandler.convert(ValueHandlerFactory.java:139)
at org.hibernate.jpa.criteria.predicate.InPredicate.<init>(InPredicate.java:130)
at org.hibernate.jpa.criteria.predicate.InPredicate.<init>(InPredicate.java:108)
at org.hibernate.jpa.criteria.CriteriaBuilderImpl.in(CriteriaBuilderImpl.java:529)
at org.hibernate.jpa.criteria.expression.ExpressionImpl.in(ExpressionImpl.java:79)

编辑:

我认为它可能与包含(Provider,Service)的ProviderService复合ID有关,定义如下:

@Id
@NotNull
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "provider_id", referencedColumnName = "provider_id", nullable = false, columnDefinition = "BIGINT UNSIGNED")
public Provider getProvider() {
    return provider;
}

public void setProvider(Provider provider) {
    this.provider = provider;
}

@Id
@NotNull
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "service_id", referencedColumnName = "service_id", nullable = false, columnDefinition = "INT UNSIGNED")
public Service getService() {
    return service;
}

public void setService(Service service) {
    this.service = service;
}

并拥有适当的IdClass如下:

public class ProviderServiceId implements Serializable {

private Long provider;
private Integer service;

/* constructors */

public ProviderServiceId() { }

public ProviderServiceId(Long providerId, Integer serviceId) {
    this.provider = providerId;
    this.service = serviceId;
}
// etc.

或者也许没有将实体属性与该属性的可能值列表(实体列表)进行比较的可能性

1 个答案:

答案 0 :(得分:0)

建议加入似乎正常工作:

getItemCount()

我认为通过传递提供者ID列表而不是提供者实体进行搜索也可以,但是没有检查它。