CriteriaQuery与一对多和多对一的关系

时间:2014-03-25 14:32:12

标签: java jpa eclipselink

我有3个问题的表:PrblFldr - > PrblFldrAtrbtVal - > PrblTmpltAtrbt。这些之间的关系是"一对多"和"多对一"分别。

我正在使用CriteriaBuilderPrblFldr个对象进行搜索。我需要搜索与PrblFldrAtrbtVal相关联的每个PrblFldr的值。查询参数'密钥是将每个PrblFldrAtrbtValPrblTmpltAtrbt相关联的唯一PK;参数的值是在PrblFldrAtrbtVal的值中搜索的内容。

到目前为止我的代码(已编辑):

@GET
@Path("/folders/search")
public Response searchFolders(@Context UriInfo uriInfo) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<PrblFldr> cq = cb.createQuery(PrblFldr.class);
    Root<PrblFldr> folder = cq.from(PrblFldr.class);
    Join<PrblFldr, PrblFldrAtrbtVal> attributes = folder.join("prblFldrAtrbtVals");
    Join<PrblFldrAtrbtVal, PrblTmpltAtrbt> attributeTemplates = attributes.join("prblTmpltAtrbt");

    List<Predicate> predicates = new ArrayList<Predicate>();
    MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();

    for (String key: queryParams.keySet()) {
        String value = queryParams.getFirst(key).replaceAll("_", "\\\\_");

        predicates.add(cb.and(cb.equal(attributeTemplates.<String>get("tmpltAtrbtSeqId"), key),
                cb.like(attributes.<String>get("fldrAtrbtVal"), "%" + value + "%", '\\')));
    }

    cq.distinct(true).select(folder).where(cb.and(predicates.toArray(new Predicate[]{})));
    List<PrblFldr> results = em.createQuery(cq).getResultList();

    return Response.ok(gson.toJson(results), MediaType.APPLICATION_JSON).build();
}

已编辑:如果我只传入一个键/值对进行搜索,目前正在运行。如果我传入多个PrblFldrAtrbtVal进行搜索,则返回空白结果集,尽管事实上一个或多个PrblFldr对象应与指定的PrblFldrAtrbtVal个对象匹配。 / p>

我认为它与cb.and()子句中的cq.where()语句有关。我确实想要&#39; AND&#39;,但为什么回来没有结果呢?

1 个答案:

答案 0 :(得分:1)

查询返回一个空列表,因为谓词添加了&#39; AND&#39;。 即,生成的查询类似于;

tmpltAtrbtSeqId = '1' AND fldrAtrbtVal like '%a%'
AND tmpltAtrbtSeqId = '2' AND fldrAtrbtVal like '%b%'
AND tmpltAtrbtSeqId = '3' AND fldrAtrbtVal like '%c%'
传递多个键/值对时

你需要添加一个&#39; OR&#39; for循环中的子句。