2014-09-25 1 views
1

Я пытаюсь получить количество пользователей в конкретной группе, я сделал следующее:Неожиданное Cross Join генерируемый SQL Использование EntityManager с Hibernate

CriteriaBuilder cb = em.getCriteriaBuilder(); 
     CriteriaQuery<Long> q = cb.createQuery(Long.class); 
     q.select(cb.count(q.from(User.class))).where(cb.equal(q.from(User.class).get("userGroup"), groupId)); 

Но вместо того, чтобы количество пользователей в группа, я получаю это число, умноженное на количество всех пользователей в моей таблице, генерируется запрос ORM выглядит следующим образом:

Hibernate: select count(*) as col_0_0_ from app_user user0_ cross join app_user user1_ where user1_.user_group=1 

EDIT:

Это мой пользователь Модель:

public class User { 
    private String userFirstName; 
    private String userLastName; 
    /* some stuff */ 
    @ManyToOne 
    private Group userGroup; 
    } 

И моя группа модель имеет атрибут ИНТ аннотированный с @Id и именем идентификатора. Как я могу получить количество пользователей по идентификатору группы в этом случае?

ответ

4

Это ожидаемое поведение. CriteriaQuery изменчив и каждый раз, когда вы звоните from(), это

Создать и добавить корень запроса, соответствующего данному объекту, образуя декартово произведение с любыми существующими корнями. (Javadoc of Java EE)

Для достижения прогнозируемого результата создайте Root один раз и используйте ссылку.

CriteriaQuery<Long> q = cb.createQuery(Long.class); 
Root<User> u = q.from(User.class); 
q.select(cb.count(u)).where(cb.equal(u.get("userGroup"), groupId)); 

В коде выше u прослушиваний ту же роль, что и в этом запросе

SELECT u.name FROM User u 

Объясняя его дальше, называя from() дважды было бы эквивалентно

SELECT u1, u2 FROM User u1, User u2 
+0

Спасибо за объяснение ... – TheByeByeMan