Unterstützung von EntityManager-Abrufplänen

Ein Abrufplan (Objekt "FetchPlan") ist die Strategie, die der Entitätsmanager für den Abruf zugeordneter Objekte verwendet, wenn die Anwendung auf Beziehungen zugreifen muss.

Beispiel

Angenommen, Ihre Anwendung hat zwei Entitäten: Department (Abteilung) und Employee (Mitarbeiter). Die Beziehung zwischen der Entität "Department" und der Entität "Employee" ist eine bidirektionale 1:N-Beziehung: Eine Abteilung hat viele Mitarbeiter, und ein Mitarbeiter gehört zu einer einzigen Abteilung. Da beim Abrufen der Entität "Department" meistens auch die Mitarbeiter abgerufen werden, wird der Abruftyp dieser 1:N-Beziehung auf EAGER (Vorsorglich) gesetzt.

Im Folgenden sehen Sie ein Snippet der Klasse "Department".

	@Entity
public class Department {

    @Id
    private String deptId;

    @Basic
    String deptName;

		@OneToMany(fetch = FetchType.EAGER, mappedBy="department", cascade = {CascadeType.PERSIST})
		public Collection<Employee> employees;

}

Wenn eine Anwendung in einer verteilten Umgebung em.find(Department.class, "dept1") aufruft, um eine Entität "Department" mit dem Schlüssel "dept1" zu suchen, findet diese Suchoperation die Entität "Department" und alle Relationen vom Typ "eager-fetched". Im Fall des vorherigen Snippets sind dies alle Mitarbeiter der Abteilung "dept1".

In den Versionen vor WebSphere eXtreme Scale 6.1.0.5 finden beim Abrufen einer Entität "Department" und N Entitäten "Employee" N+1 Client/Server-Austauschoperationen statt, weil der Client nur eine einzige Entität pro Client/Server-Austausch abruft. Sie können die Leistung verbessern, wenn Sie diese N+1 Entitäten in einem einzigen Austausch abrufen.

Abrufplan

Ein Abrufplan (FetchPlan) kann verwendet werden, um um festzulegen, wie Beziehungen vom Typ "eager" abgerufen werden, indem die maximale Beziehungstiefe angepasst wird. Die Abruftiefe setzt alle Relationen vom Typ "eager" auf "lazy", die größer sind als die festgelegte Abruftiefe. Standardmäßig ist die Abruftiefe die maximale Abruftiefe. Das bedeutet, dass Beziehungen vom Typ "eager" aller Ebenen, die aus Eager-Sicht über die Stammentität erreicht werden können, abgerufen werden. Eine Beziehung vom Typ "eager" ist nur dann aus Eager-Sicht über eine Stammentität erreichbar, wenn alle Beziehungen ausgehend von der Stammentität zu dieser Eager-Beziehung als Eager-Fetched-Beziehungen konfiguriert sind.

Im vorherigen Beispiel ist die Entität "Employee" über die Entität "Department" aus Eager-Sicht erreichbar, weil die Beziehung zwischen Department und Employee als Eager-Fetched-Beziehung konfiguriert ist.

Wenn die Entität "Employee" beispielsweise eine weitere Eager-Beziehung zu einer Entität "Address" hat, ist die Entität "Address" aus Eager-Sicht ebenfalls über die Entität "Department" erreichbar. Sind die Department-Employee-Beziehungen jedoch als Lazy-Fetched-Beziehungen konfiguriert, ist die Entität "Address" aus Eager-Sicht nicht über die Entität "Department" erreichbar, weil die Department-Employee-Beziehung die Eager-Fetch-Kette unterbricht.

Ein FetchPlan-Objekt kann von der EntityManager-Instanz abgerufen werden. Die Anwendung kann die Methode "setMaxFetchDepth" verwenden, um die maximale Abruftiefe zu ändern.

Ein Abrufplan wird einer EntityManager-Instanz zugeordnet. Der Abrufplan gilt für jede Abrufoperation, die im Folgenden einzeln aufgeführt sind:

Das FetchPlan-Objekt ist veränderlich. Sobald das Objekt geändert wird, wird der geänderte Wert auf die anschließend ausgeführten Abrufoperationen angewendet.

Ein Abrufplan ist für eine verteilte Implementierung wichtig, weil er entscheidet, ob die Eager-Fetched-Beziehungsentitäten mit der Stammentität in einer einzigen oder in mehreren Client/Server-Austauschoperationen abgerufen werden.

Stellen Sie sich als Fortsetzung des vorherigen Beispiels vor, dass der Abrufplan eine definierte maximale Tiefe von unbegrenzt hat. Wenn eine Anwendung in diesem Fall em.find(Department.class, "dept1") aufruft, um eine Abteilung (Department) zu suchen, ruft diese Suchoperation eine einzige Department-Entität und N Employee-Entitäten in einer einigen Client/Server-Austauschoperation ab. Bei einem Abrufplan mit einer maximalen Abruftiefe von null wird jedoch nur das Department-Objekt vom Server abgerufen, während die Employee-Entitäten nur dann vom Server abgerufen werden, wenn auf die Employee-Sammlung des Department-Objekts zugegriffen wird.

Verschiedene Abrufpläne

Sie haben mehrere verschiedene Abrufpläne, die auf Ihren Anforderungen basieren und in den folgenden Abschnitten beschrieben werden.

Auswirkung auf ein verteiltes Grid

Wichtig: Wenn eine Beziehung sortiert ist (mit der Annotation "OrderBy" oder durch Konfiguration), wird sie auch dann als Eager-Beziehung betrachtet, wenn sie als Lazy-Fetched-Beziehung konfiguriert ist.

Leistungshinweise in einer verteilten Umgebung

Standardmäßig werden alle Beziehungen, die aus Eager-Sicht über die Stammentität erreichbar sind, in einer einzigen Client/Server-Autauschoperation abgerufen. Dies kann die Leistung verbessern, wenn alle Beziehungen verwendet werden. In bestimmten Einsatzszenarien werden jedoch nicht alle aus Eager-Sicht über die Stammentität erreichbaren Beziehungen verwendet. Der Abruf dieser nicht verwendeten Entitäten bedeutet also einen erhöhten Aufwand für die Laufzeitumgebung und eine Einschränkung der Bandbreite.

Für solche Fälle kann die Anwendung die maximale Abruftiefe auf einen kleineren Wert setzen, um die Tiefe der abzurufenden Entitäten zu verringern, indem alle Eager-Relationen nach dieser Tiefe als Lazy-Relationen definiert werden. Diese Einstellung kann die Leistung verbessern.

Zur weiteren Fortsetzung des vorherigen Department-Employee-Address-Beispiels werden jetzt alle Address-Entitäten, die Mitarbeitern der Abteilung "dept1" zugeordnet sind, wenn em.find(Department.class, "dept1") aufgerufen wird. Wenn die Anwendung keine Address-Entitäten verwendet, kann sie die maximale Abruftiefe auf 1 setzen, so dass die Address-Entitäten nicht zusammen mit der Entität "Department" abgerufen werden.