2010-10-19 23 views
14

Supongamos que tengo una entidad Post y una entidad comentario y una relación de uno a muchos:¿Cómo puedo hacer la paginación con colecciones @OneToMany

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

¿Cómo puedo lograr paginación así:

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

¿Es posible emular la paginación dinámica con colecciones @OneToMany sobre JPA, o tenemos que reescribir el mecanismo de asociación de JPA totalmente? (por ejemplo, cree un tipo de colección PersistentList que pueda administrar la búsqueda, la clasificación y la búsqueda).

P.S .: ¡Recientemente encontré la Play! framework usa una lib muy interesante encima de JPA: Siena. Siena es muy fácil de usar, y es una buena abstracción de JPA/Hibernate. Pero no puedo encontrar cómo hacer paginación con sus asociaciones.

Actualización:

framework Play tiene una sintaxis de consulta similar a Django:

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

donde

Post.findAll() 

devolverá un objeto JPAQuery, un tipo de consulta personalizada en Reproducir.

Pero con colecciones asociadas, por ejemplo .:

Post.comments 

se acaba de regresar de una lista, que no soporta paginación u otras consultas.

Me preguntaba cómo extender, de manera que

Post.comments 

también devolver un objeto JPAQuery o similar, entonces se puede consultar en la colección "consulta":

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

o inserto un nuevo comentario sin realmente obtener ninguno de los comentarios:

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

En mi primer pensamiento, pudimos crear una subclase de la lista, entonces la clase del anuncio se convertiría en:

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

y QueryList habrá fetch(), a partir de() métodos que indirecta a JPAQuery de.

Pero no sé si Hibernate/JPA lo reconocerá o interferirá con él.

Respuesta

7

¿Es posible emular paginación dinámica con colecciones @OneToMany en la parte superior de la APP (...)

No compatible. El enfoque estándar sería usar una consulta JPQL para recuperar los comentarios de una publicación determinada y usar Query#setFirstResult(int) y Query#setMaxResults(int).

En mi primer pensamiento, podríamos crear una subclase de Lista, (...).Pero no sé si Hibernate/JPA lo reconocerá o interferirá con él.

Obviamente, no sin un parche pesada para cambiar drásticamente el comportamiento predeterminado.

+0

cierto. Descubrí que Hibernate "interceptará" la Colección @OneToMany e indirectamente en una consulta. Entonces, ¿es posible "completar" el sistema Hibernate con un tipo de colección personalizada (por ejemplo, @OneToMany LazyQueryList, que tiene un método fetch (inicio, compensación)) que Hibernate reconocerá? –

+1

@Visus Debería ser posible ** parchear ** Hibernar, que es muy diferente de un mecanismo de complemento, y esto no será un parche trivial. Buena suerte si decides ir en esta dirección. –

+0

Gracias por la aclaración. Soy nuevo con Hibernate, y un parche pesado definitivamente supera mi capacidad. Pero todavía estoy atascado con cómo usar las asociaciones de manera efectiva. Te vi hablar de proyectos que utilizan hibernación de una manera incorrecta: "no usamos asociaciones porque tenían miedo de" recuperar toda la base de datos ", en una respuesta a otra pregunta. Realmente me gustaría saber cómo NO recuperar una colección completa. O, en el caso de crear manualmente consultas JPQL para la colección, ¿significa eso que utilizamos la colección de asociación solo para la asignación? ¿Cómo podemos volver a establecerlos en Post.comments? –

3

creo que la forma "correcta" podría ser más como:

@Entity 
class Post { 
    ... 

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

y luego utilizar una de las fetchmethods en JPAQuery:

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