문제의 테이블이 3 개인 : PrblFldr -> PrblFldrAtrbtVal -> PrblTmpltAtrbt. 이들 사이의 관계는 각각 "일대 다"및 "다 대일"입니다.일대 다 및 다 대일 관계가있는 CriteriaQuery
을 사용하여 PrblFldr
개체에 대한 검색을 수행하고 있습니다. 각 PrblFldrAtrbtVal
의 값으로 검색해야하는데이 값은 PrblFldr
과 관련이 있습니다. 쿼리 매개 변수의 키는 각 PrblFldrAtrbtVal
을 PrblTmpltAtrbt
과 연결하는 고유 한 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
개체와 일치해야 함에도 불구하고 빈 결과 집합이 반환됩니다.
cq.where()
절에있는 cb.and()
문과 관련이 있다고 생각합니다. 나는 'AND'를 원하지만 왜 결과가 돌아 오지 않는가?
아,하지만 대신 OR 절을 배열로 변환 할 때 술어에 사용하고 싶지 않습니까? 나는 for-loop의 두 문장이 AND'ed가되도록하고 값과'tmpltAtrbtSeqId'가 올바른'PrblFldrAtrbtVal'와 일치하도록하고 싶습니다. –
제안을 시도한 후 원래 게시물을 편집했습니다. 새로운 문제를 참조하십시오. –
나는 당신이 쿼리에 'DISTINCT'를 추가해야한다고 생각한다. http://stackoverflow.com/questions/10731723/how-to-add-distinct-in-hibernate-criteria – Priyesh