简体   繁体   中英

Unexpected Cross Join Generated SQL Using EntityManager with hibernate

I'm Trying to get the number of user in a specific group, I've done the following :

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));

But instead of getting the number of user in a group , I get this number multiplied by the number of all users in my table, the generated ORM request looks like this :

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

EDIT :

This is my user Model :

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

And my group model has an int attribute annotated with @Id and named id. How Can I get the number of user by group id in this case ?

This is the expected behaviour. CriteriaQuery is mutable and every time you call from() , it

Create and add a query root corresponding to the given entity, forming a cartesian product with any existing roots. (Javadoc of Java EE)

To achieve predictable result please create Root once and use the reference.

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));

Within above code u plays same role as in this query

SELECT u.name FROM User u

Explaining it further, calling from() twice would be equivalent of

SELECT u1, u2 FROM User u1, User u2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM