Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 ?

like image 701
TheByeByeMan Avatar asked Apr 17 '26 22:04

TheByeByeMan


1 Answers

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
like image 68
zbig Avatar answered Apr 20 '26 12:04

zbig



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!