Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate - HQL to fetch a collection from Unidirectional OneToMany relationship

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.

like image 211
mogronalol Avatar asked Nov 24 '11 09:11

mogronalol


People also ask

What is the default mechanism for representing one to many unidirectional relationships in JPA?

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.

What makes a one to many relationship as bidirectional relationship?

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.

What is cross join in HQL?

More than one entity can also appear in HQL which will perform cartesian product that is also known as cross join.


1 Answers

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.

like image 165
JB Nizet Avatar answered Oct 24 '22 21:10

JB Nizet