편집 :이 게시물을 완전히 편집하여 문제의 새로운 설명에 이전에 관련이 있다고 생각했던 것뿐만 아니라 모든 세부 정보가 포함되도록했습니다. . 어쩌면이 새로운 설명은 제가 직면하고있는 문제를 해결하는 데 도움이 될 것입니다.Projections.count()와 Projections.countDistinct() 모두 동일한 쿼리 결과가 발생합니다.
두 개의 엔티티 클래스 인 Customer 및 CustomerGroup이 있습니다. 고객 그룹과 고객 그룹 간의 관계는 ManyToMany입니다. 고객 그룹은 고객 클래스에서 다음과 같은 방식으로 주석이 작성됩니다.
@Entity
public class Customer {
...
@ManyToMany(mappedBy = "customers", fetch = FetchType.LAZY)
public Set<CustomerGroup> getCustomerGroups() {
...
}
...
public String getUuid() {
return uuid;
}
...
}
고객 그룹 클래스의 고객 참조는 다음과 같은 방법으로 CustomerGroup 및 고객 클래스 모두는 또한 UUID 필드를 가지고
@Entity
public class CustomerGroup {
...
@ManyToMany
public Set<Customer> getCustomers() {
...
}
...
public String getUuid() {
return uuid;
}
...
}
참고 주석된다. UUID는 고유 한 문자열입니다 (고유 한 문자열은 다른 일반 문자열과 마찬가지로 처리되므로 데이터 모델에서 고유하지 않습니다.
내가하려는 것은 고객 그룹에 속하지 않은 모든 고객을 가져 오거나 고객 그룹을 "유효한 그룹"으로 가져 오는 것입니다. 고객 그룹의 유효성은 유효한 UUID 목록으로 정의됩니다.
나는 그러나 하나를 가진 쿼리를 실행할 때
Criteria criteria = getSession().createCriteria(Customer.class);
criteria.setProjection(Projections.countDistinct("uuid"));
criteria = criteria.createCriteria("customerGroups", "groups", Criteria.LEFT_JOIN);
List<String> uuids = getValidUUIDs();
Criterion criterion = Restrictions.isNull("groups.uuid");
if (uuids != null && uuids.size() > 0) {
criterion = Restrictions.or(criterion, Restrictions.in(
"groups.uuid", uuids));
}
criteria.add(criterion);
, 그것은 내가 원하는 것을 다음 SQL 쿼리 쿼리는 정확히
select
count(*) as y0_
from
Customer this_
left outer join
CustomerGroup_Customer customergr3_
on this_.id=customergr3_.customers_id
left outer join
CustomerGroup groups1_
on customergr3_.customerGroups_id=groups1_.id
where
groups1_.uuid is null
or groups1_.uuid in (
?, ?
)
가 발생합니다 다음 기준 쿼리
을 만들었습니다 예외. 고객은 여러 고객 그룹에 속할 수 있기 때문에 CustomerGroup에 가입하면 고객 오브젝트가 중복됩니다. 따라서count(*)
은 얼마나 많은 결과가 있는지 계산하기 때문에 잘못된 값을 제공합니다. 나는 유일한 고객의 양을 얻고 나는 이것을
Projections.countDistinct("uuid");
투영을 사용하여 달성 할 것으로 예상했다. 어떤 이유로 인해 볼 수 있듯이 프로젝션은 여전히
count(distinct uuid)
대신
count(*)
쿼리가 발생합니다. 프로젝션
countDistinct
을
count("uuid")
으로 바꾸면 정확히 동일한 쿼리가됩니다.
내가 잘못했거나 버그입니까?
===
"문제"가 해결되었습니다. 이유 : PEBKAC (키보드와 의자 사이에 문제가 있음). 내 코드에 분기가 있었고 분기가 실행되었음을 알지 못했습니다. 해당 분기는 countDistinct() 대신 rowCount()를 사용합니다.
을 확장합니다. 조건을 사용하여 기본 쿼리를 작성한 후 수동으로 왼쪽 조인을 수동으로 추가하는 경우 : 그 방법은 아닙니다. – Fortega
문제점과 관련된 모든 코드를 포함하도록 질문을 편집했습니다. –
같은 문제를 겪고있는 다른 사람들은 다음 질문을 참조하십시오. http://stackoverflow.com/questions/4616607/projections-countdistinct-with-hibernate-produces-unexpected-result – simon