2010-12-21 11 views
0

Erstens ist dies das erste Mal, dass ich Hibernate verwende, so dass meine Fragen naiv erscheinen.Hibernate Fremdschlüssel relation - list() macht unnötige SQL Abfragen - setMaxResults ignoriert

Ich habe zwei Tabellen, DsJobs und DsEvents. Ereignisse haben eine Fremdschlüsselbeziehung in der DsJobs-Tabelle (die EID-Spalte in der DsJobs-Tabelle entspricht der ID-Spalte der DsEvents-Tabelle).

ich das Mapping mit anotations creted haben, was mich interessiert, ist einseitige Beziehung, so habe ich eine ‚dsEvents‘ Eigenschaft in DsJobs Tabelle mit @ManyToOne kommentierte:

@Entity 
@Table(name="DsJobs") 
public class DsJobs implements java.io.Serializable { 

... 

    private DsEvents dsEvents; 
    ... 

    @Id 
    @Column(name="JID", unique=true, nullable=false) 
    public long getJid() { 
     return this.jid; 
    } 

    public void setJid(long jid) { 
     this.jid = jid; 
    } 

@ManyToOne 
    @JoinColumn(name="eid") 

    public DsEvents getDsEvents() { 
     return this.dsEvents; 
    } 

    public void setDsEvents(DsEvents dsEvents) { 
     this.dsEvents = dsEvents; 
    } 
.... 
} 

ich die Liste abrufen möchten von Setzt Datensätze aus der Datenbank und beschränkt sie auf setFirstResult und setMaxResults. Das ist der Ruf i machen:

return (ArrayList<DsJobs>) this.sessionFactory.getCurrentSession().createQuery("from DsJobs log").setFirstResult(start).setMaxResults(rows).list(); 

Dieser Code eine Arraylist von DsJobs Objekt zurückgibt und im Inneren jedes DsJobs Objekt gibt es ein DsEvents Objekt, richtig instanziiert.

Meine Fragen sind zwei:

  1. Wenn ich die HQL sehen ausgeführt dort werden die Anrufe an die Datenbank unnecesery SELECT, eine für jeden DsJobs Rekord. Daher gibt es für jeden DsJobs-Datensatz ein SELECT in den DsEvents, um das entsprechende Ereignis nach Ereignis-ID abzurufen. Dies ist inakzeptabel für die Performance, da ich mit einer einfachen JDBC alle Daten, die ich brauche, mit einer inneren Verknüpfung SELECT STATM bekommen kann. Ich mache wahrscheinlich etwas völlig falsches, bitte lassen Sie mich wissen, was und wenn Sie wissen, wie ich vorgehen soll.

  2. Die SetFirstResult und SetMaxResults scheinen vollständig von Hibernate ignoriert werden, ich bekomme immer alle Datensätze aus der Datenbank. Wie kann ich das beheben?

Ich werde jede Hilfe sehr schätzen.

Vielen Dank im Voraus.

Antwort

1

Wenn ich sehe, dass die HQL ausgeführt wird, gibt es unnötige SELECT-Aufrufe an die Datenbank, eine für jeden DsJobs-Datensatz.

Ja, das ist das gefürchtete n + 1 Auswahlproblem. Dies geschieht nur, wenn Sie eine RI-Einschränkung für Ihre Beziehung erzwingen (z. B. Eins-zu-Eins-Constraints oder eindeutige Constraints). Das Mapping, das Sie uns zeigen, scheint diese Probleme nicht zu haben, was mich glauben lässt, dass Sie uns nicht das tatsächliche Mapping zeigen, das Ihnen Probleme bereitet. Bitte posten Sie den eigentlichen Code, nicht eine verallgemeinerte, abgekürzte Version.

Die setFirstResult und setMaxResults scheinen vollständig von Hibernate ignoriert werden, ich bekomme immer alle Datensätze aus der Datenbank. Wie kann ich das beheben?

Dieser Code ist auch in Ordnung.Was bedeutet, dass Sie uns nicht den tatsächlichen Code zeigen, der Ihnen Probleme bereitet.

+0

Dies ist genau mein Problem, danke für Ihre Antwort. Ich habe nicht das vollständige Verständnis, warum dies passiert, aber ich war in der Lage, das erste Problem mit dieser Abfrage zu beheben: aus DsJobs Log links Join Fetch Log.dsEvents. – alex

0

Für 1, möchten Sie vielleicht über Lazy/Eager laden lesen. In Ihrem Fall scheint es, Sie wollen Eager laden, dh alle Daten auf einmal abrufen. Weitere Informationen finden Sie auf dieser Wiki-Seite: http://community.jboss.org/wiki/AShortPrimerOnFetchingStrategies

Für 2 klingt Ihre Verwendung korrekt. Ich würde mehr Details benötigen, um zu sehen, wie es falsch ist.