2010-10-19 10 views
14

Supponiamo che io sono un'entità Post e un'entità commento e uno a molti:Come posso fare il paging con le collezioni @OneToMany

@Entity class Post { 
    ... 
    @OneToMany 
    List<Comment> comments; 
    ... 
} 

Come posso realizzare paging in questo modo:

Post post = //Find the post. 
return post.getComments().fetch(100, 10); // Find the 11th page (page size 10); 

È possibile emulare il paging dinamico con le collezioni @OneToMany su JPA, oppure è necessario riscrivere totalmente il meccanismo di associazione di JPA? (ad esempio, creare un tipo di raccolta PersistentList che possa gestire il paging, l'ordinamento e la ricerca).

P.S .: Recentemente ho trovato il gioco! framework usa una libreria molto interessante sopra JPA: Siena. Siena è molto facile da usare, ed è una buona astrazione su JPA/Hibernate. Ma non riesco a trovare come fare il paging con le sue associazioni.

Aggiornamento:

quadro Play ha una sintassi di query simile a Django:

Post.findAll().from(100).fetch(10); // paging 

dove

Post.findAll() 

restituisce un oggetto JPAQuery, un tipo di query personalizzata in Play.

Ma con collezioni associati, ad es .:

Post.comments 

sarà solo restituire un elenco, che non supporta il paging o di altre query.

mi chiedevo come estendere, in modo che

Post.comments 

anche restituire un oggetto JPAQuery o simili, allora si può interrogare sul "query" collezione:

Post.comments.from(100).fetch(10); 

o inserto un nuovo commento senza recuperare alcun commento:

Post.comments.add(new Comment(...)); 

Al mio primo pensiero, potremmo creare una sottoclasse di List, allora la classe messaggio sarebbe diventato:

@Entity class Post { 
    ... 
    @OneToMany 
    QueryList<Comment> comments; 
    ... 
} 

e QueryList avrà fetch(), dai metodi() che indiretto a JPAQuery di.

Ma non so se Hibernate/JPA riconoscerà questo o interferirà con esso.

risposta

7

E 'possibile emulare paging dinamico con collezioni @OneToMany sulla parte superiore del JPA (...)

Non supportato. L'approccio standard sarebbe utilizzare una query JPQL per recuperare i commenti per un determinato post e utilizzare Query#setFirstResult(int) e Query#setMaxResults(int).

Al mio primo pensiero, è possibile creare una sottoclasse di Elenco, (...).Ma non so se Hibernate/JPA riconoscerà questo, o interferirà con esso.

E, ovviamente, non sarà senza un cerotto pesante di cambiare drasticamente il comportamento predefinito.

+0

BTW. Ho scoperto che Hibernate "intercetterà" la raccolta @OneToMany e indiretta in una query. Quindi è possibile "integrare" il sistema Hibernate con un tipo di raccolta personalizzato (ad esempio @OneToMany LazyQueryList, che ha un metodo di recupero (avvio, offset)) che Hibernate riconoscerà? –

+1

@Visus Dovrebbe essere possibile ** patch ** Hibernate, che è molto diverso da un meccanismo di plugin, e questa non sarà una patch banale. Buona fortuna se decidi di andare in questa direzione. –

+0

Grazie per il chiarimento. Sono nuovo con l'ibernazione e una patch pesante è decisamente al di fuori delle mie capacità. Ma sono ancora bloccato su come utilizzare le associazioni in modo efficace. Ti ho visto parlare di progetti che utilizzano la modalità ibernazione in modo negativo - "non utilizzare le associazioni perché avevano paura di" recuperare l'intero database "", in una risposta a un'altra domanda. Mi piacerebbe davvero sapere come NON recuperare un'intera collezione. Oppure, nel caso di creazione manuale di query JPQL per la raccolta, vuol dire che utilizziamo la raccolta di associazioni solo per la mappatura? Come possiamo riportarli su Post.comments? –

3

penso che il modo "giusto" potrebbe essere più simile:

@Entity 
class Post { 
    ... 

    public GenericModel.JPAQuery getComments() { 
     return Comment.find("post_id = ?", post_id); 
    } 
} 

e quindi utilizzare uno dei fetchmethods in JPAQuery:

// fetch first page of results, 25 results per page 
post.getComments().fetch(1,25); 
Problemi correlati