2011-11-24 11 views
8

mi hanno una classe con uno unidirezionale ai molti rapporto come segue:Hibernate - HQL per andare a prendere una collezione dal rapporto unidirezionale OneToMany

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

Normalmente ottenere i contenuti di questo ordine è semplice:

List<Item> items = order.getItems(); 

Ma per qualche ragione potrei voler filtrare i miei risultati in qualche modo e recuperare solo una parte di una collezione di articoli come tutti gli articoli più di un certo prezzo, sotto un certo stock ecc nel modo più veloce possibile (non ritorna poi tutto quindi filtrare in seguito). Per fare ciò, eseguo una query HQL per recuperare gli elementi per un particolare ordine e aggiungere altro materiale nella mia clausola where o sul mio oggetto query.

Intuitivamente vorrei questo comportamento (che è completamente sbagliato):

SELECT jointable.ITEM from order_item as jointable inner join jointable.order where order = :order 

Ma naturalmente questo è sbagliato, come funziona HQL in termini di entità mappate, quindi non posso utilizzare la tabella unirsi alla query. Allora, qual è il modo corretto per farlo?

Edit:

ho trovato la risposta a questa domanda, voglio la seguente query:

Select o.items from Order o where o = ? 

Questo mi permette di prendere la collezione di articoli per un ordine, senza dover utilizzare una relazione bidirezionale. Ora sono tuttavia confuso sulla seconda fase di questa domanda, che è come filtrare i risultati di questa collezione, l'esempio più semplice essere:

Select o.items from Order o where o = ? order by o.items.somenumberfield asc 

che restituisce tentativo illegale di raccolta dereferenziare, così come mi sarebbe filtrare i miei oggetti?

Edit:

La soluzione biglietto è in realtà corretto, ho letto male la soluzione originariamente.

risposta

6
select item from Order order 
inner join order.items item 
where order = :order 
and ... 

Le query HQL utilizzano le entità e le relative associazioni. Il fatto che l'associazione usi una tabella di join o meno non è importante per HQL: si naviga attraverso le associazioni e Hibernate esegue la traduzione appropriata in SQL.

+0

grazie per il vostro aiuto, vedere la mia modifica – mogronalol

3

Sembra che si desideri mappare l'altro lato di questa relazione, ovvero creare questa mappatura bidirezionale.

quindi è possibile utilizzare il numero d'ordine nella vostra HQL:

from Item as item where item.amount > :amount and item.order.id = :orderId 

Dal HQL documentation:

dal gatto come il gatto dove cat.mate.id = 69 La query è efficiente e non richiede un join di tabella.

Il fatto che si stia tentando di eseguire questa query suggerisce che la relazione tra una linea e il relativo ordine è importante!

+1

Non c'è bisogno di rendere l'associazione bidirezionale. Vedi la mia risposta. –

+0

Non è necessario. Ciò non significa che non dovresti. I documenti di Hibernate spiegano che l'HQL per questa istanza è ottimizzato per la situazione in cui hai mappato entrambi i lati. –

+0

grazie per il tuo aiuto, vedi la mia modifica – mogronalol

Problemi correlati