2015-07-23 13 views
6

Ci sono molte domande a riguardo ma non sono riuscito a trovare una risposta concreta. Sono nuovo di Hibernate e sto cercando di implementare l'impaginazione. Diciamo che ho due entità: padre e figlio, che sono definite come segue:Impaginazione in sospensione con tavoli uniti

@Entity 
@Table(name="Parents") 
public class Parent{ 

    @Id 
    @Column(name="id", length=255) 
    private String id; 

    @Column(name="name", length=255) 
    protected String name; 

    @OneToMany 
    @JoinTable(name="parents_children", joinColumns = @JoinColumn(name="parent_id"), inverseJoinColumns = @JoinColumn(name="child_id")) 
    @LazyCollection(LazyCollectionOption.FALSE) 
    protected List<Child> children; 
} 

@Entity 
@Table(name="children") 
public class Child { 

    @Id 
    @Column(name="id", length=255) 
    protected String id; 

    @Column(name="name", length=255) 
    protected String name; 


    } 

Ogni struttura dispone anche di getter e setter come richiesto.

voglio ottenere la prima pagina di di genitoriordinati per nome, dove ogni pagina è 10 risultati.

così ho iniziato da:

Session session = HibernateUtil.getSessionFactory().openSession(); 
    Criteria c = session.createCriteria(Parent.class, "p"); 
    c.createAlias("q.children", "ch"); 
    c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); 
    c.addOrder(Order.desc("name")); 
    c.setMaxResults(10); 
    c.setFirstResult(0); 
    List<Parent> result = c.list(); 
    session.close(); 

Questo codice non funziona come previsto perché le setMaxResults viene eseguita sul tavolo unito e non sulla lista genitori (come io voglio che sia).

La mia domanda è quale dovrebbe essere la query per ottenere il paging nell'elenco dei genitori e non sulla tabella unita?

risposta

1

L'impaginazione non funziona con le raccolte unite perché conta tutte le righe che hanno soddisfatto il predicato where (Hibernate non ha nulla a che fare con questo, è come funzionano i database, ad esempio Oracle rownum).

Il modo usuale per superare questo problema è utilizzare le sottoquery, in modo che rownum (o l'equivalente nel database utilizzato) venga applicato alle righe selezionate di una sola tabella (o tabelle unite che si trovano in relazioni to-one).

In HQL:

select p from Parent p were p in (select c.parent from Child c where ...) 

Il criteria equivalent possono essere costruiti in modo simile.

+0

Potresti fornire la query sql più efficiente per l'impaginazione (sto usando mysql)? –

+0

In base a ciò che hai fornito nella domanda (pagina attraverso i genitori che hanno figli), la query più efficiente dovrebbe essere esattamente quello che ho fornito nella risposta: 'selezionare p da Parent p erano p in (selezionare c.parent da Child c) '. –

0

hai utilizzato c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) per trovare distinto Parent che si sta eseguendo dopo che i dati provengono dal database. Dopo aver commentato questa riga si otterrà l'output corretto ma i duplicati sono duplicati.

Dopo aver valutato il problema, ho trovato un collegamento su StackOverflow correlato al problema. Ti aiuterà a seguire il seguente link. Stackoverflow Criteria Pagging