2012-10-08 3 views
10

Angenommen, Artikel und Gebot sind Entitäten: ein Artikel hat viele Gebote. Sie werden in Hibernate in einem typischen Eltern/Kind-Beziehung abgebildet:Kriterien eifrige fetch-joined-Auflistung, um n + 1 zu vermeiden, wählt

<class name="Item" table="ITEM"> 
    ... 
    <set name="bids" inverse="true"> 
    <key column="ITEM_ID"/> 
    <one-to-many class="Bid"/> 
    </set> 
</class> 

Wie kann ich n + 1 wählt vermeiden, wenn die Gebote der einzelnen Artikel zuzugreifen versuchen, nachdem diese Abfrage ausgeführt wird?

List<Item> items = session.createCriteria(Item.class) 
         .createAlias("bids", "b"). 
         .add(Restrictions.gt("b.amount", 100)). 
         .list(); 

Hinweis Ich brauche eine eifrig für Gebote aber mit einer weiteren Beschränkung der Sammlung holen (b.amount> 100)

Ich habe folgendes erfolglos versucht:

List<Item> items = session.createCriteria(Item.class) 
         .setFetchMode("bids", FetchMode.JOIN). 
         .createAlias("bids", "b"). 
         .add(Restrictions.gt("b.amount", 100)). 
         .list();       

List<Item> items = session.createCriteria(Item.class) 
         .createCriteria("bids") 
         .add(Restrictions.gt("amount", 100)). 
         .list();       
+0

http://stackoverflow.com/questions/617145/hibernate-fetching-strategy-when-to-use-join-and-when-to-use-select Ich denke, es wird vorher gefragt .... –

Antwort

6

Dies ist eine Erklärung, warum auf dem Abruf verbundene Sammlung eine Beschränkung Hinzufügen bewirkt, dass die Sammlung nicht initialisiert wurde (Notiz, die die gleiche Abfrage ohne Einschränkung ein eifrige für die Sammlung produzieren holen):

"Wenn Sie eine 1: n-Beziehung zwischen den Tabellen A und B haben und B eine Einschränkung hinzufügen und A und B abfragen möchten, wäre die Frage, was passiert, wenn Sie von A nach A navigieren möchten B. Sollten Sie nur die Daten in B sehen, die der Einschränkung entsprechen, oder sollten Sie alle Bs sehen, die verwandt sind zu einem?" see more here ...

jedoch mit HQL anstelle von Kriterien, holen teilweise die

Es scheint mir eine Inkonsistenz

List<Item> items = session.createQuery(
      "from Item i left join fetch i.bids b where b.amount > :amount") 
      .setParameter("amount", 100) 
      .list(); 
Sammlungen Gebote, aber es ist, wie diese

Durch die Art und Weise funktioniert, Wenn Sie brauchen, ist die Liste der Eltern und aller Kinder, aber nur die Eltern, deren Kinder alle bestimmte Einschränkungen erfüllen, so dass Sie diese

verwenden können
List<Item> items = session.createQuery(
      "from Item i left join fetch i.bids b " + 
      "where not exists (from Bid b where b.item = i and b.amount <= :amount)") 
      .setParameter("amount", 100) 
      .list(); 

Dies ist eine verwandte Beiträge: Hibernate query not returning full object.

9

Diese Kriterienabfrage scheint richtig zu sein:

List<Item> items = session.createCriteria(Item.class) 
        .setFetchMode("bids", FetchMode.JOIN) 
        .createAlias("bids", "b") 
        .add(Restrictions.gt("b.amount", 100)) 
        .list(); 

FetchMode.JOIN soll lösen n+1 Problem. Haben Sie einige default_batch_fetch_size | definiert batch-size irgendwo im Mapping oder in der Konfiguration, was umgekehrt wirkt?

Wenn nicht, können Sie bitte unter HQL versuchen und sehen, dass dies Ihr Problem löst?

Query query = 
     session.createQuery("from Item it left join it.bids b where b.amount=:bids"); 
query.setParamter(bids, 100); 
List<Item> items = query.list(); 
1

Ich denke, was Sie brauchen, ist ein Kriterium, das Subquery Exists auf anderen Kriterien verwendet.Eine ähnliche Antwort ist hier: https://stackoverflow.com/a/15768089/1469525

DetachedCriteria criteria = session.createCriteria(Item.class, "i"); 
criteria.setFetchMode("bids", FetchMode.JOIN); 

DetachedCriteria bidCriteria = DetachedCriteria.forClass(Bid.class, "b"); 
bidCriteria.add(Restrictions.gt("amount", 100)); 
bidCriteria.add(Restrictions.eqProperty("b.itemId", "i.id")); 
criteria.add(Subqueries.exists(bidCriteria.setProjection(Projections.property("b.id")))); 
Verwandte Themen