|
In der in der EJB 3.0-Spezifikation enthaltenen Spezifikation der Java Persistence API sind zwei Fetching-Strategien definiert und aufgeführt: Lazy Load und Eager Load. Im Vergleich zu Hibernate und anderen Persistence Providern wie TopLink sind das noch „wenige“ Optionen. Sowohl aus Zeit- als auch aus Aufwandsgründen sind in der EJB 3.0-Fassung keine weiteren Fetching-Strategien definiert. Eine Detaillierung und Erweiterung der Fetching-Strategien ist voraussichtlich für die kommende Version geplant.
Die Eager Load-Strategie ist innerhalb der Java Persistence API durchweg als Standard voreingestellt. Lazy Load kommt nur dann zur Anwendung, wenn der Entwickler dies explizit angibt. Der Eager Load-Mechanismus ist verpflichtend durch die Hersteller der Persistence Provider Runtimes (z.B. Hibernate) zu implementieren und zur Verfügung zu stellen. Bei Lazy Load ist es zurzeit noch so, dass die Angabe von Lazy Load „lediglich“ als Hinweis für die Persistence Provider Runtime gesehen wird und nicht weiter spezifiziert ist, in welcher konkreten Ausprägung / Umsetzung der Lazy Load-Mechanismus tatsächlich zur Verfügung gestellt und genutzt wird.
Momentan sieht es so aus, dass für EJB 3.0 die Umsetzung des Lazy Load-Mechanismus den Herstellern der Persistence Provider Runtimes obliegt und nicht weiter spezifiziert wird. Dies birgt natürlich eine Menge Gefahren wie beispielsweise eine nicht mögliche Gewährleistung der Interoperabilität durch divergierende architektonische und technische Umsetzungen der Hersteller.
Wie und wo wird die zu verwendende Fetching-Strategie deklariert?
Die Angabe der von der Persistence Provider Runtime zu verwendenden Fetching-Strategie kann an verschiedenen Elementen im Code erfolgen.
Attribute
Für jedes persistentes Attribut einer Entität bzw. eines Objektes kann direkt bei den Mapping-Informationen des Attributes die Fetching-Strategie hinterlegt werden. Dazu kann zusätzlich zur @Column-Annotation die Annotation @Basic(fetch=FetchType.LAZY), @Basic(fetch=FetchType.EAGER), @Serialized(fetch=FetchType.LAZY) bzw. @Serialized(fetch=FetchType.EAGER) angegeben werden.
Die Angabe der zu verwendenden Fetching-Strategie auf Attributebene ist optional. Wird bei einem persistenten Attribut keine diesbezügliche Angabe vorgenommen, geht die Persistence Provider Runtime von dem Standardverhalten des Eager Loadings (fetch=FetchType.EAGER) aus.
Java Persistence QL-Abfragen
Innerhalb von Java Persistence QL-Abfragen besteht die Möglichkeit in der FROM-Klausel einer Abfrage eine Fetching-Strategie anzugeben. Diese werden als so genannte „Fetch Joins“ bezeichnet und sind von der Hibernate HQL inspiriert. Fetch Joins werden dafür genutzt die Beziehungen zwischen einer Entität und deren abhängigen Enitäten bereits beim Ausführen der Java Persistence QL-Abfrage mit aufzulösen und ein Prefetching der abhängigen Entitäten vorzunehmen. Das originäre Resultset enthält nur die Ergebnismenge der primären Abfrage. D.h. die abhängigen Entitäten sind nicht Bestandteil der Ergebnismenge der Abfrage. Bei der Navigation über Objekte aus dieser Ergebnismenge kann jedoch sehr schnell auf deren abhängigen Objekte zugegriffen werden, da diese bereits vorgeladen worden sind.
Deklaration von Beziehungen
Bei der Deklaration der Beziehung von einer Entität zu einer anderen durch Verwendung einer der Annotationen @OneToOne, @OneToMany, @ManyToOne, @ManyToMany kann als Element jeder dieser Annotationen (fetch=FetchType.LAZY) oder (fetch=FetchType.EAGER) angegeben werden. Diese Angabe sorgt dafür, dass der Entity Manager die referenzierten Objekte entsprechend der gewählten Strategie sofort oder erst auf konkreten Zugriff hin aus der Datenbank liest bzw. lädt.
Die Angabe der zu verwendenden Fetching-Strategie ist optional. Wird das fetch-Element nicht angegeben, geht die Persistence Provider Runtime von dem Standardverhalten des Eager Loadings (fetch=FetchType.EAGER) aus.
Anzumerken ist, dass diese Informationen auch über die Deployment Deskriptoren angegeben werden können. Als Wertigkeitsregel gilt hier, dass die Deklaration mittels XML im Deployment Deskriptor die Deklaration schlägt, die über Annotationen angegeben worden sind.
|