JPAEntityLoader-Plug-in

Das JPAEntityLoader-Plug-in ist eine integrierte Loader-Implementierung, die Java Persistence API (JPA) verwendet, um mit der Datenbank zu kommunizieren, wenn Sie die API "EntityManager" verwenden. Wenn Sie die API "ObjectMap" verwenden, verwenden Sie den Loader "JPALoader".

Details zum Loader

Verwenden Sie das JPALoader-Plug-in, wenn Sie Daten mit der API "ObjectMap" speichern. Verwenden Sie das JPAEntityLoader-Plug-in, wenn Sie Daten mit der API "EntityManager" speichern.

Loader (Ladeprogramme) stellen zwei Hauptmethoden bereit:
  1. get: In der Methode "get" ruft das JPAEntityLoader-Plug-in zunächst die Methode "javax.persistence.EntityManager.find(Class entityClass, Object key)" auf, um die JPA-Entität zu suchen. Anschließend projiziert das Plug-in diese JPA-Entität auf Entitätstupel. Während der Projektion werden die Tupelattribute und die Assoziationsschlüssel im Werttupel gespeichert. Nach der Verarbeitung der einzelnen Schlüssel gibt die Methode "get" eine Liste mit Entitätswerttupel zurück.
  2. batchUpdate: Die Methode "batchUpdate" verwendet ein LogSequence-Objekt, das eine Liste mit LogElement-Objekten enthält. Jedes LogElement-Objekt enthält ein Schlüsseltupel und ein Werttupel. Für die Interaktion mit dem JPA-Provider muss zunächst auf der Basis des Schlüsseltupels die eXtreme-Scale-Entität gesucht werden. Basierend auf dem LogElement-Typ werden die folgenden JPA-Aufrufe ausgeführt:
    • insert: javax.persistence.EntityManager.persist(Object o)
    • update: javax.persistence.EntityManager.merge(Object o)
    • remove: javax.persistence.EntityManager.remove(Object o)
Ein LogElement-Objekt mit dem Typ update veranlasst JPAEntityLoader, die Methode "javax.persistence.EntityManager.merge(Object o)" aufzurufen, um die Entität aufzunehmen. Ein LogElement-Objekt des Typs update kann das Ergebnis eines Aufrufs der Methode "com.ibm.websphere.objectgrid.em.EntityManager.merge(object o)" oder einer Attributänderung in der von der eXtreme-Scale-API "EntityManager" verwalteten Instanz sein. Sehen Sie sich das folgende Beispiel an:
com.ibm.websphere.objectgrid.em.EntityManager em = og.getSession().getEntityManager();
em.getTransaction().begin();
Consumer c1 = (Consumer) em.find(Consumer.class, c.getConsumerId());
c1.setName("New Name");
em.getTransaction().commit();

In diesem Beispiel wird ein LogElement-Objekt des Typs "update" an den JPAEntityLoader des Map-Konsumenten gesendet. Die Methode "javax.persistence.EntityManager.merge(Object o)" im JPA-EntityManager wird an Stelle einer Attributaktualisierung in der von JPA verwalteten Entität aufgerufen. Aufgrund dieses geänderten Verhaltens sind eine Einschränkungen bei der Verwendung dieses Programmiermodells zu beachten.

Regeln für das Anwendungsdesign

Entitäten haben Beziehungen mit anderen Entitäten. Beim Design einer Anwendung mit Beziehungen und mit dem JPAEntityLoader-Plug-in müssen weitere Aspekte berücksichtigt werden. Die Anwendung muss vier Regeln einhalten, die im Folgenden beschrieben werden.

Eingeschränkte Unterstützung für die Beziehungstiefe

JPAEntityLoader wird nur unterstützt, wenn Entitäten ohne Beziehungen bzw. Beziehungen mit einer einzigen Beziehungsebene verwendet werden. Beziehungen mit mehreren Ebenen, wie z. B. Company > Department > Employee, werden nicht unterstützt.

Ein einziger Loader pro Map

Angenommen Sie haben eine Entitätsbeziehung "Consumer-ShippingAddress". Wenn Sie einen Konsumenten laden, der sehr viele Abrufe durchführt, können Sie alle zugehörigen ShippingAddress-Objekte laden. Wenn Sie ein Customer-Objekt als persistent definieren oder aufnehmen, können Sie die zugehörigen ShippingAddress-Objekte als persistent definieren oder aufnehmen, wenn "cascade-persist" oder "cascade-merge" aktiviert ist.

Sie können keinen Loader für die Stammentitäts-Map integrieren, in der die Consumer-Entitätstupel gespeichert werden. Sie müssen für jede einzelne Entitäts-Map einen Loader konfigurieren.

Derselbe Kaskadierungstyp für JPA und eXtreme Scale

Stellen Sie sich wieder den Fall vor, dass der Entitätskonsument (Consumer) eine Eins-zu-viele-Beziehung zu ShippingAddress hat. Angenommen, für diese Beziehung ist "cascade-persist" aktiviert. Wenn ein Consumer-Objekt in eXtreme Scale als persistent definiert wird, werden die zugehörigen N ShippingAddress-Objekte in eXtreme Scale ebenfalls als persistent definiert.

Ein Aufruf der Methode "persist" für das Consumer-Objekt mit einer Beziehung vom Typ "cascade-persist" zu ShippingAddress von der JPAEntityLoader-Schicht in einen Aufruf der Methode "javax.persistence.EntityManager.persist(consumer)" und N Aufrufe der Methode "javax.persistence.EntityManager.persist(shippingAddress)" übersetzt. Diese N zusätzlichen Aufrufe von "persist" an die ShippingAddress-Objekte sind jedoch wegen der Einstellung "cascade-persist" aus der Sicht des JPA-Providers nicht erforderlich. Zur Lösung dieses Problems stellt eXtreme Scale eine neue Methode "isCascaded" in der Schnittstelle "LogElement" bereit. Die Methode "isCascaded" gibt an, ob das LogElement-Objekt das Ergebnis einer Operation "cascade" des EntityManager von eXtreme Scale ist. In diesem Beispiel empfängt der JPAEntityLoader der Map "ShippingAddress" wegen der cascade-persist-Aufrufe N LogElement-Objekte. Der JPAEntityLoader stellt fest, dass die Methode "isCascaded" den Wert "true" zurückgibt und ignoriert sie daraufhin, ohne JPA-Aufrufe abzusetzen. Deshalb wird aus der JPA-Sicht nur ein einziger Aufruf der Methode "javax.persistence.EntityManager.persist(consumer)" abgerufen.

Dasselbe Verhalten zeigt sich, wenn Sie eine Entität aufnehmen oder eine Entität entfernen, wenn die Kaskadierung aktiviert ist. Die kaskadierten Operationen werden vom JPAEntityLoader-Plug-in ignoriert.

Die Kaskadierungsunterstützung ist so konzipiert, dass die Operationen des EntityManager von eXtreme Scale an die JPA-Provider wiederholt werden. Zu diesen Operationen gehören die Operationen "persist", "merge" und "remove". Damit dies funktioniert, müssen Sie sicherstellen, dass die Kaskadierungseinstellungen von JPA und EntityManager von eXtreme Scale identisch sind.

Entitätsaktualisierung mit Vorsicht verwenden

Wie bereits beschrieben, ist die Kaskadierungsunterstützung so konzipiert, dass die Operationen des EntityManager von eXtreme Scale an die JPA-Provider wiederholt werden. Wenn Ihre Anwendung die Methode "ogEM.persist(consumer)" im EntityManager von eXtreme Scale aufruft, werden selbst die zugeordneten ShippingAddress-Objekte aufgrund der Einstellung "cascade-persist" persistent gespeichert, und der JPAEntityLoader ruft nur die Methode "jpAEM.persist(consumer)" in den JPA-Providern auf.

Wenn Ihre Anwendung jedoch eine verwaltete Entität aktualisiert, wird diese Aktualisierung vom JPAEntityLoader-Plug-in in einen JPA-Aufruf "merge" übersetzt. In diesem Szenario ist die Unterstützung für mehrere Beziehungsebenen und Schlüsselzuordnungen nicht gewährleistet. In diesem Fall bewährt es sich, die Methode "javax.persistence.EntityManager.merge(o)" zu verwenden, anstatt eine verwaltete Entität zu aktualisieren.