2014-03-25 4 views
0

문제의 테이블이 3 개인 : PrblFldr -> PrblFldrAtrbtVal -> PrblTmpltAtrbt. 이들 사이의 관계는 각각 "일대 다"및 "다 대일"입니다.일대 다 및 다 대일 관계가있는 CriteriaQuery

을 사용하여 PrblFldr 개체에 대한 검색을 수행하고 있습니다. 각 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 개체와 일치해야 함에도 불구하고 빈 결과 집합이 반환됩니다.

cq.where() 절에있는 cb.and() 문과 관련이 있다고 생각합니다. 나는 'AND'를 원하지만 왜 결과가 돌아 오지 않는가?

답변

1

술어에 'AND'가 추가되어 조회가 빈 목록을 리턴합니다. 즉, 생성되는 쿼리는 다음과 같습니다.

tmpltAtrbtSeqId = '1' AND fldrAtrbtVal like '%a%' 
AND tmpltAtrbtSeqId = '2' AND fldrAtrbtVal like '%b%' 
AND tmpltAtrbtSeqId = '3' AND fldrAtrbtVal like '%c%' 

여러 키/값 쌍을 전달할 때.

for 루프에 'OR'절을 추가해야합니다.

+0

아,하지만 대신 OR 절을 배열로 변환 할 때 술어에 사용하고 싶지 않습니까? 나는 for-loop의 두 문장이 AND'ed가되도록하고 값과'tmpltAtrbtSeqId'가 올바른'PrblFldrAtrbtVal'와 일치하도록하고 싶습니다. –

+0

제안을 시도한 후 원래 게시물을 편집했습니다. 새로운 문제를 참조하십시오. –

+0

나는 당신이 쿼리에 'DISTINCT'를 추가해야한다고 생각한다. http://stackoverflow.com/questions/10731723/how-to-add-distinct-in-hibernate-criteria – Priyesh

관련 문제