Frage

In Bezug auf meine frühere Frage , möchte ich alle gewährleisten die Kind-Objekte geladen werden, da ich eine mehr Threads habe, die auf die Daten zugreifen können müssen (und damit träges Laden Ausnahmen vermeiden). Ich verstehe die Art und Weise, dies zu tun ist, um das „holen“ Schlüsselwort in der Abfrage (EJB QL) zu verwenden. Wie folgt aus:

select distinct o from Order o left join fetch o.orderLines

Unter der Annahme ein Modell mit einer Order Klasse, die eine Reihe von OrderLines in sich hat.

Meine Frage ist, dass die „distinct“ Schlüsselwort erforderlich zu sein scheint, wie ich sonst scheinen eine Order für jeden OrderLine zu kommen. Bin ich das Richtige zu tun?

Vielleicht noch wichtiger ist, ist es eine Möglichkeit, in allen untergeordneten Objekten zu ziehen, egal wie tief? Wir haben etwa 10 bis 15 Klassen und für den Server werden wir alles geladen brauchen ... ich vermied mit FetchType.EAGER als dass seine bedeutete stets darauf bedacht, und insbesondere das Webfrontend Lasten alles - aber vielleicht ist der Weg zu gehen - ist dass das, was Sie tun? Ich glaube mich zu erinnern, uns dies versuchen, vor und dann langsam Webseiten immer wirklich - aber vielleicht das bedeutet, sollten wir einen Second-Level-Cache-Speicher werden mit

War es hilfreich?

Lösung

die Anmerkung zu ändern, ist eine schlechte Idee, IMO. Da es nicht zu faul zur Laufzeit geändert werden. Besser alles faul, und holt nach Bedarf.

Ich bin mir nicht sicher, ob ich Ihr Problem ohne Zuordnungen zu verstehen. LEFT JOIN holen sollte alles, was Sie für den Anwendungsfall benötigen werden Sie beschreiben. Natürlich werden Sie eine Bestellung für jeden Bestellposten zurück, wenn order einen Auftrag als Elternteil hat.

Andere Tipps

Ich bin nicht sicher über die holen Keyword in Ihrer EJBQL verwenden, könnten Sie es verwirrt mit dem Vermerk bekommen ...

Haben Sie versucht, die FetchType Eigenschaft, um Ihre Beziehung Attribut hinzufügen?

@OneToMany (Fetch = FetchType.EAGER)?

Siehe auch:

http://java.sun.com/ JavaEE / 5 / docs / api / javax / Persistenz / FetchType.html http://www.jroller.com/eyallupu/entry/hibernate_exception_simultaneously_fetch_multiple

Haben Sie versucht, ein Ergebnis Transformator? Wenn Sie Kriterien Abfragen verwenden, können Sie ein Ergebnis Wandlers (obwohl es einige Probleme mit Paginierung und Ergebnis sind Transformator ):

Criteria c = ((Session)em.getDelegate()).createCriteria(Order.class);
c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
c.list();

die em.getDelegate() ist ein Hack, der nur funktioniert, wenn Sie Hibernate verwenden.

  

Vielleicht noch wichtiger ist, gibt es eine   Art und Weise in allen untergeordneten Objekten zu ziehen, nein   Unabhängig davon, wie tief? Wir haben etwa 10 bis 15   Klassen und für den Server werden wir   muß alles geladen ... Ich war   mit FetchType.EAGER wie die Vermeidung von   gemeint sein immer eifrig und in   insbesondere die Web-Front-End-Lasten   alles - aber vielleicht ist das   Weg zu gehen - ist es das, was Sie tun? ich   scheinen uns versuchen, sich daran zu erinnern, bevor   und dann bekommen wirklich langsam Webseiten   - aber vielleicht das bedeutet, sollten wir einen Second-Level-Cache-Speicher werden mit

Wenn Sie immer noch interessiert sind, antwortete ich eine ähnliche Frage in diesem Thread wie Hibernate Sammlungen serialisiert .

Im Grunde verwenden Sie ein Programm namens Planierraupe die Bohnen auf eine andere Bohnen abbildet, und durch dieses Tun Sie alle auslösen Ihre faulen Lasten. Wie Sie sich vorstellen können, das funktioniert besser, wenn alle Sammlungen eifrig geholt werden.

Das könnte Sie der Lage sein, etwas zu tun, wie die Verwendung eines (freistehend) Kriterien Abfrage und Einstellung der Modus holen. Z.B.

Session s = ((HibernateEntityManager) em).getSession().getSessionFactory().openSession();
DetachedCriteria dc = DetachedCriteria.forClass(MyEntity.class).add(Expression.idEq(id));
dc.setFetchMode("innerTable", FetchMode.JOIN);
Criteria c = dc.getExecutableCriteria(s);
MyEntity a = (MyEntity)c.uniqueResult();

Das nur für ManyToOne Beziehungen funktionieren würde und für sie @ManyToOne (Fetch = FetchType.EAGER) würde wahrscheinlich angemessen.

Fetching mehr als eine OneToMany Beziehung eifrig abgeraten und / oder nicht funktioniert, wie Sie in dem Link Jeremy geschrieben lesen können. Man denke nur an die SQL-Anweisung, die benötigt würde, zu tun, eine solche holen ...

Was ich getan habe ist, den Code Refactoring Karte von Objekten zu Entity-Manager zu halten und jedes Mal, wenn ich aktualisieren müssen, schließen Sie das alte EntityManager für das Objekt und öffnen Sie ein neues. Früher habe ich die obige Abfrage ohne den holen , wie das geht zu tief für meine Bedürfnisse - nur ein einfachen verbinden zieht in dem Orderlines zu tun - der holen macht es geht noch tiefer.

Es gibt nur wenige Objekte, die ich brauche dies für rund 20, so dass ich denke, die Overhead-Ressource 20 offen entitymanagers in aufweist, ist kein Problem - obwohl die DBAs eine andere Ansicht haben kann, wenn diese live geht ...

ich auch überarbeitet Dinge so, dass die db Arbeit auf dem Hauptthread ist und die Einheit-Manager.

Chris

Wenn das Problem nur LazyInitializationExceptions ist, können Sie das vermeiden, indem sie einen OpenSessionInViewFilter hinzufügen.
Auf diese Weise können die Objekte in der Ansicht geladen werden, wird aber nicht mit der Geschwindigkeit Problem helfen.

     <filter>
        <filter-name>hibernateFilter</filter-name>
        <filter-class> org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>hibernateFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top