意外的交叉连接使用带有hibernate的EntityManager生成的SQL

The*_*Man 3 sql hibernate jpa entitymanager

我正在尝试获取特定组中的用户数量,我已完成以下操作:

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));
Run Code Online (Sandbox Code Playgroud)

但是,不是获取组中的用户数,而是将此数字乘以表中所有用户的数量,生成的ORM请求如下所示:

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

编辑:

这是我的用户模型:

public class User {
    private String userFirstName;
    private String userLastName; 
    /* some stuff */
    @ManyToOne
    private Group userGroup;
    }
Run Code Online (Sandbox Code Playgroud)

我的组模型有一个用@Id和named id注释的int属性.在这种情况下,如何获取组ID的用户数?

zbi*_*big 7

这是预期的行为.CriteriaQuery是可变的,每次你打电话from(),它

创建并添加与给定实体对应的查询根,形成具有任何现有根的笛卡尔积.(Java EE的Javadoc)

要获得可预测的结果,请创建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));
Run Code Online (Sandbox Code Playgroud)

在上面的代码中u扮演与此查询中相同的角色

SELECT u.name FROM User u
Run Code Online (Sandbox Code Playgroud)

进一步解释,调用from()两次将相当于

SELECT u1, u2 FROM User u1, User u2
Run Code Online (Sandbox Code Playgroud)