I have an Class with a unidirectional one to many relationship as follows:
public class Order {
@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name="order_item", joinColumns={@JoinColumn(name="order_id")}, inverseJoinColumns={@JoinColumn(name="item_id")})
public Set<Item> getItems() {
return items;
}
}
Normally getting the contents of this order is straightforward:
List<Item> items = order.getItems();
But for whatever reason I might want to filter my results in some way and retrieve only part of a collection of items such as all items more than a certain price, below a certain stock etc in the fastest way possible (Not returning then all then filtering afterwards). To do this I would run a HQL query to retrieve the items for a particular order and add some more stuff into my where clause or onto my query object.
Intuitively I would want this behaviour (Which is completely wrong):
SELECT jointable.ITEM from order_item as jointable inner join jointable.order where order = :order
But of course this is wrong as HQL works in terms of mapped entities, so I cannot use the join table in the query. So what is the correct way to do this?
Edit:
I have found the answer to this question, I want the following Query:
Select o.items from Order o where o = ?
This allows me to fetch the collection of items for an order, without having to use a bidirectional relationship. I am now however confused on the second stage of this question, which is how to filter the results of this collection, the most simple example being:
Select o.items from Order o where o = ? order by o.items.somenumberfield asc
Which returns illegal attempt to dereference collection, so how would I filter my items?
Edit:
The ticket solution is actually correct, I misread the solution originally.
As straightforward as it might be in a relational database, when it comes to JPA, the one-to-many database association can be represented either through a @ManyToOne or a @OneToMany association since the OOP association can be either unidirectional or bidirectional.
The way this works at the database level is we have a cart_id as a primary key in the cart table and also a cart_id as a foreign key in items. The way we do it in code is with @OneToMany. We can also add a reference to Cart in each Item using @ManyToOne, making this a bidirectional relationship.
More than one entity can also appear in HQL which will perform cartesian product that is also known as cross join.
select item from Order order
inner join order.items item
where order = :order
and ...
HQL queries use entities and their associations. The fact that the association uses a join table or not is not important for HQL: you navigate through associations and Hibernate does the appropriate translation to SQL.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With