使用Hibernate的EntityManager时生成了意外的交叉连接SQL

3
我正在尝试获取特定组中用户的数量,我已经完成以下操作:
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

编辑:

这是我的用户模型:

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

我的群组模型有一个 int 属性,使用 @Id 注释,并命名为 id。在这种情况下,我如何通过群组 id 获取用户数量?

1个回答

9
这是预期行为。 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));

在上述代码中,u 的作用与此查询中相同。
SELECT u.name FROM User u

更进一步的解释,调用两次from()将等同于
SELECT u1, u2 FROM User u1, User u2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接