JPA Criteria基于条件过滤集合

时间:2017-08-03 02:59:05

标签: java oracle jpa criteria openjpa

为什么Criteria查询不根据服务(集合实体)条件 services.get(“status”),“pending”)过滤记录,如下所示?

CriteriaQuery<Customer> query = cb.createQuery(Customer.class);
    Root<Customer> customer = query.from(Customer.class);
Join<Customer, Service> services = customer.join("services", JoinType.INNER);

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

predicates.add(cb.equal(customer.get("customerId"), 1));
predicates.add(cb.equal(services.get("status"), "pending"));

query.select(customer).distinct(true)
        .where(predicates.toArray(new Predicate[]{}));

List<Customer> customers = em.createQuery(query).getResultList();

SQL在哪里正确过滤记录

  select * from customers c
  INNER JOIN SERVICES s on s.COID = c.COID 
  where c.ID=1 and
  s.status='pending';

根据状态条件(用于收集),结果集中的记录不合格,实际上,返回了客户的所有服务。

我尝试使用fetch Join(因为有2个查询是第一次为客户执行,第2次是针对该客户的服务,思想条件可能未在第二次查询中评估)

customer.fetch("services", JoinType.INNER);

但没有运气。

我对这种行为感到惊讶。我正在使用OpenJPA JPA提供程序

实体客户服务

 public class Customer{
    @Id
    @Column(name = "ID")
    private Integer customerId;
    @OneToMany
    @MappedBy(name = "customer")
    private List<Service> services;
    }

 public class Service {
    @EmbeddedId
    private ServicesPK servicePK;
    @ManyToOne
    @JoinColumn(name = "COID")
    private Customer customer;
    }

 @Embeddable
 @EqualsAndHashCode
 public class ServicesPK implements Serializable {
    @Column(name = "COID")
    private Integer coId;
    @Column(name = "VERSION")
    private Integer version;
}

1 个答案:

答案 0 :(得分:1)

尝试此代码,我做的更改是我在查询中添加了类型安全性。关于类型安全typesafe

CriteriaQuery<Customer> query = cb.createQuery(Customer.class);
Root<Customer> customer = query.from(Customer.class);
Join<Customer, Service> services = customer.join(Customer_.services);
List<Predicate> predicates = new ArrayList<Predicate>();

predicates.add(cb.equal(customer.get("customerId"), 1));
predicates.add(cb.equal(services.get(Service_.status), "pending"));

query.select(customer).distinct(true)
    .where(predicates.toArray(new Predicate[]{}));

List<Customer> customers = em.createQuery(query).getResultList();