Ignorieren FetchType.EIFRIG in einer Beziehung
Ich habe ein problem mit EAGERs Beziehungen in einer großen Anwendung. Einige Entitäten, die in dieser Anwendung haben EAGER
Assoziationen mit anderen Entitäten. Diese "Gift" in bestimmten Funktionen.
Nun mein team braucht, um dies zu optimieren, Funktionalitäten, aber können wir nicht ändern, den fetch-Typ zu FAUL, weil wir Sie brauchen würden, um die Umgestaltung der gesamten Anwendung.
So, meine Frage: gibt es einen Weg, um eine bestimmte Abfrage zu ignorieren die EAGERs Assoziationen in meinem zurückgegebene Entität?
Beispiel: wenn ein ich habe diese Entität Person, ich möchte nicht die Adresse-Liste, wenn ich eine Abfrage, eine Person zu finden.
@Entity
public class Person {
@Column
private String name;
@OneToMany(fetch=FetchType.EAGER)
private List<String> address;
}
Query query = EntityManager.createQuery("FROM Person person");
//list of person without the address list! But how???
List<Person> resultList = query.getResultList();
Dank!
Aktualisiert
Der einzige Weg, fand ich nicht wieder die Person, wenn nur einige Felder der Entität. Aber ich möchte eine Lösung finden, dass ich zurückkehren kann, die Entität (in meinem Beispiel die Person
Person).
Ich denke, wenn ist möglich, Karte die gleiche Tabelle zweimal in den Ruhezustand versetzt werden. Auf diese Weise kann ich die Zuweisung des gleichen Tabelle, ohne die EIFRIGEN Verbände. Dies wird mir helfen, in wenigen Fällen...
- stackoverflow.com/questions/10997321/...
- Vielleicht sind Sie besser dran, refactoring. In der Regel BEGIERIG, würde nur verwendet werden für triviale Beziehungen, wenn, die. Besser, alles, was FAUL und dann Holen Sie sich die extra, wenn Sie wirklich wissen, Sie es brauchen.
- Hi @Nikolaus! Es ist die bessere Lösung. Leider ist es nicht möglich, umgestalten, alle Entitäten, da es eine Menge von Auswirkungen in der Anwendung.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie mit JPA 2.1 (Hibernate 4.3+) Sie können erreichen, was Sie wollen mit @NamedEntityGraph.
Im Grunde, würden Sie kommentieren Ihre Person wie diese:
Und verwenden Sie dann die Hinweise zu Holen, Person ohne Adresse, wie z.B.:
Mehr zum Thema können gefunden werden hier.
Wenn Sie die fetch-Diagramm nur die Felder, die Sie in @NamedEntityGraph geholt werden eifrig.
Alle vorhandenen Abfragen, die ausgeführt werden ohne den Hinweis wird gleich bleiben.
Eigentlich nie versucht, diese, aber möglicherweise einen Versuch Wert... Vorausgesetzt, dass die session factory ist erhältlich bei der DAO-Schicht mittels Injektion oder andere Mittel, die Sie implementieren können, etwas ähnliches in eine (wahrscheinlich neue) DAO-Methode:
FetchMode.LAZY
ist veraltet und entspricht esFetchMode.SELECT
. SoFetchMode.LAZY
führt tatsächlich brennen eine zusätzliche SELECT-Abfrage zu eifrig laden Sie die Sammlung. Das nicht wirklich laden Sie die Sammlung LAZYily.Standardmäßig Hibernate ist HQL, Kriterien-und NativeSQL gibt uns die Flexibilität, um Eifrig laden Sie eine Sammlung, wenn es zugeordnet ist, als FAUL im domain-Modell.
Bezug auf die andere Weg-Runde, dh., mapping der Sammlung, wie EIFRIG in der Domäne, Modell und versuchen zu tun, LAZY load mit HQL, Kriterien oder NativeSQL, ich konnte Sie nicht finden, eine gerade vorwärts-oder den einfacheren Weg, in dem wir uns treffen können diese mit HQL/Kriterien/NativeSQL.
Obwohl wir
FetchMode.LAZY
, dass wir auf Kriterien,ist es veraltet und es ist äquivalent zuFetchMode.SELECT
. Und effektiv FetchMode.FAUL, tatsächlich zu brennen eine zusätzliche SELECT-Abfrage und noch eifrig lädt die Sammlung.Aber, wenn wir wollen, um LAZY load eine Sammlung zugeordnet ist, wie EIFRIG Sie können versuchen, diese Lösung: Stellen Sie die HQL/Kriterien/NativeSQL zurückgeben scalar-Werte und verwenden Sie eine
ResultTransformer(Transformers.aliasToBean(..))
Rückkehr der entity-Objekt (DTO) mit gefüllten Feldern aus skalaren Werten.In meinem Szenario, ich habe eine Wald Entität, die hat eine Sammlung von Baum Personen mit oneToMany Zuordnung von
FetchType.EAGER
undFetchMode.JOIN
. Zum laden nur das Wald Einheit ohne laden alle Bäume, die ich verwendet habe die folgende HQL-query mit Skalare Werte und Transformatoren.aliasToBean(...). Dies funktioniert mit Kriterien und Native SQL sowie lange Skalare und aliasToBean Transformator verwendet wird.Forest forest = (Forest) session.createQuery("select f.id as id, f.name as name, f.version as version from Forest as f where f.id=:forest").setParameter("forest", i).setResultTransformer(Transformers.aliasToBean(Forest.class)).uniqueResult();
Habe ich getestet für über einfache Abfrage-und es könnte sein, arbeiten überprüfen, ob dies funktioniert für komplexe Fälle als gut und passend für alle Ihre Anwendungsfälle.
Wäre gespannt zu erfahren, ob es einen besseren oder einfacheren Weg, es zu tun, vor allem ohne Skalare und Transformatoren.
Ihnen nicht sagen, warum Sie konnte es nicht ändern, aus begierig zu faul. Ich jedoch habe den Eindruck, dass es aus performance-Gründen und so möchte ich diese Annahme in Frage zu stellen. Wenn das der Fall ist, beachten Sie bitte die folgenden. Ich merke, dass diese Antwort nicht unbedingt beantworten Ihre Frage, und es verletzt die Bedingung ohne die lazy geladen, aber hier ist eine alternative, die spiegelt mein dev-team-Ansatz zu dem, was ich denke, ist das gleiche zugrunde liegende Problem.
Festlegen des fetch-Typs zu faul, aber dann setzen Sie ein @BatchSize-annotation. Da hibernate in der Regel wird ein separater DB-Abfrage zu laden, eine Sammlung, so bleibt das Verhalten aber mit einem abgestimmten BatchSize, vermeiden Sie 1 Abfrage pro element (zwar in einer Schleife, z.B.) - vorausgesetzt, Ihre Sitzung noch geöffnet ist.
Das Verhalten für die backref eine OneToOne-Beziehung wird ein wenig witzig (die betroffene Seite der Beziehung - Seite, ohne den foreign key). Aber für die andere Seite der OneToOne, für OneToMany ManyToOne und erhält das Ergebnis, dass ich denke, Sie wollen wahrscheinlich: nur die Abfrage der Tabellen, wenn Sie Sie wirklich benötigen, aber vermeiden Sie eine lazy load pro Datensatz, und Sie muss nicht explizit konfigurieren Sie jeden Anwendungsfall. Dies bedeutet, dass Ihre Leistung wird vergleichbar bleiben in der Veranstaltung, die Sie ausführen, die faul Last, aber diese Last wird nicht passieren, wenn Sie nicht wirklich brauchen es.
Nach all diesen Jahren, überschreiben die EIFRIGEN mapping ist noch nicht möglich auf Hibernate. Aus der neueste Hibernate-Dokumentation (5.3.10.Final):
Und: