Reputation: 9065
I recently dig into Hibernate and found two ways to do an inner join query using HQL, but I don't know what's the difference between them and which one to use.
Let's assume that we have two tables:
Table user
+-------+-----------+-----------+
|userId |userName | userLevel |
+-------+-----------+-----------+
|1001 |James | 0 |
+-------+-----------+-----------+
|1002 |Tom | 2 |
+-------+-----------+-----------+
Table order
+----------+-----------+-----------+----------+
|orderId |userId |productId |fee |
+----------+-----------+-----------+----------+
|1001 |1002 |1003 | 5 |
+----------+-----------+-----------+----------+
|1002 |1002 |1005 | 50 |
+----------+-----------+-----------+----------+
|1003 |1001 |1010 | 30 |
+----------+-----------+-----------+----------+
User Tom could have multi order records in the order
table. And here comes a demand that we want to find some the order information of Tom alone with his name, if it is raw sql
we could do this:
select user.userId, user.userName, order.orderId, order.fee from user join order where user.userId=order.userId and user.userId=1002;
But on coming to hibernate I found two ways that could achieve this:
using the one-to-many
mapping to connect the relation between user and order and make a orderEntities<Set>
in the userEntity
definition then make a HQL query like this:
FROM UserEntity as U INNER JOIN U.orderEntities as O WHERE U.userId=1002;
Or
omit the one-to-many
definition and just make a HQL query like this:
FROM UserEntity U, OrderEntity O WHERE U.userId = O.userId AND U.userId=1002;
What's the different between these two ways of querying? And which one should I use?
Upvotes: 0
Views: 209
Reputation: 692073
Both are wrong, and BTW, the SQL query is wrong as well.
The first one has an inner join that is useless. The only effect of the join is that it will cause the query to not return anything if the user doesn't have any order. If the goal is to retrieve the user by ID, and then to access its orders, then you shouldn't even use a query:
UserEntity u = em.find(UserEntity.class, 1002);
Set<OrderEntity> orders = u.getOrderEntities();
That will however execute two queries: one to load the user, and a second one to load the orders if you actually do something with them (like iterate on them, getting the size of the set, or whatever)
If the goal is to load the user and its orders in a single query, then the query should be
select distinct u from UserEntity u
left join fetch u.orderEntities
where u.id = 1002
Note the usage of a left join, and the usage of fetch.
The second one is wrong because it uses O.userId
, which should not exist. If the order entity needs to know its user, then you should have a ManyToOne association from Order to User. Never a field holding the ID of another entity.
Upvotes: 1