Ein ObjectGrid kann eine beliebige Anzahl logischer Entitätsschemas haben. Entitäten werden über annotierte Java-Klassen, XML oder eine Kombination von XML und Java-Klassen definiert. Definierte Entitäten werden anschließend bei einem Server von eXtreme Scale registriert und an BackingMaps, Indizes und andere Plug-ins gebunden.
Lokale Konfiguration von eXtreme Scale
Wenn Sie ein lokales ObjectGrid verwenden, können Sie das Entitätsschema über das Programm konfigurieren. In diesem Modus können Sie die Methoden ObjectGrid.registerEntities verwenden, um annotierte Entitätsklassen oder Deskriptordatei für die Entitätsmetadaten zu registrieren.Verteilte eXtreme-Scale-Konfiguration
Wenn Sie eine verteilte eXtreme-Scale-Konfiguration verwenden, müssen Sie eine Deskriptordatei für die Entitätsmetadaten mit dem Entitätsschema angeben.Weitere Einzelheiten finden Sie unter EntityManager in einer verteilten Umgebung.
Entitätsmetadaten werden mit Java-Klassendateien und/oder einer XML-Entitätsdeskriptordatei konfiguriert. Die Mindestvoraussetzung ist die XML-Entitätdeskriptordatei, die die eXtreme-Scale-BackingMaps identifiziert, die Entitäten zugeordnet werden sollen. Die persistenten Attribute der Entität und die Beziehungen der Entität zu anderen Entitäten werden in einer annotierten Java-Klasse (Entitätsmetadatenklasse) oder in der XML-Entitätsdeskriptordatei beschrieben. Die Entitätsmetadatenklasse, sofern angegeben, wird auch von der API "EntityManager" für die Interaktion mit den Daten im Grid verwendet.
Ein eXtreme-Scale-Grid kann ohne Bereitstellung von Entitätsklassen definiert werden. Dies kann hilfreich sein, wenn der Server und der Client direkt mit den Tupeldaten interagieren, die in den zugrunde liegenden Maps gespeichert sind. Solche Entitäten werden vollständig in der XML-Entitätsdeskriptordatei definiert und als klassenlose Entitäten bezeichnet.
Klassenlose Entitäten sind hilfreich, wenn es nicht möglich ist, Anwendungsklassen in den Server- oder Clientklassenpfad einzuschließen. Solche Entitäten werden in der XML-Deskriptordatei für die Entitätsmetadaten definiert. Der Klassenname der Entität wird mit einer Kennung für klassenlose Entitäten in der Form @<Entitätskennung> angegeben. Das Symbol @ kennzeichnet die Entität als klassenlos und wird für die Zuordnungsassoziationen zwischen Entitäten verwendet. In der Abbildung "Metadaten einer klassenlosen Entität" finden Sie ein Beispiel für eine XML-Deskriptordatei für Entitätsmetadaten mit zwei definierten klassenlosen Entitäten.
Wenn ein eXtreme-Scale-Server oder -Client keinen Zugriff auf die Klassen hat, kann er die API "EntityManager" weiterhin mit klassenlosen Entitäten verwenden. Einige der gängigen Anwendungsfälle sind im Folgenden aufgeführt:
Wenn die Entitätsmetadaten von Client und Server kompatibel sind, können Entitätsmetadaten mit Entitätsmetadatenklassen und/oder einer XML-Datei erstellt werden.
Die Klasse "Programmgesteuerte Entitätsklasse" in der folgenden Abbildung ist beispielsweise mit dem klassenlosen Metadatencode im nächsten Abschnitt kompatibel:
Programmgesteuerte Entitätsklasse
@Entity
public class Employee {
@Id long serialNumber;
@Basic byte[] picture;
@Version int ver;
@ManyToOne(fetch=FetchType.EAGER, cascade=CascadeType.PERSIST)
Department department;
}
@Entity
public static class Department {
@Id int number;
@Basic String name;
@OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL, mappedBy="department")
Collection<Employee> employees;
}
Wie zuvor erwähnt, werden klassenlose Entitäten vollständig in der XML-Entitätsdeskriptordatei konfiguriert. Klassenbasierte Entitäten definieren ihre Attribute mit Java-Feldern, -Eigenschaften und -Annotationen. Deshalb müssen klassenlose Entitäten die Schlüssel- und Attributstruktur im XML-Entitätsdeskriptor mit den Tags <basic> und <id> definieren.
Metadaten einer klassenlosen Entität
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://ibm.com/ws/projector/config/emd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ibm.com/ws/projector/config/emd ./emd.xsd">
<entity class-name="@Employee" name="Employee">
<attributes>
<id name="serialNumber" type="long"/>
<basic name="firstName" type="java.lang.String"/>
<basic name="picture" type="[B"/>
<version name="ver" type="int"/>
<many-to-one
name="department"
target-entity="@Department"
fetch="EAGER"">
<cascade><cascade-persist/></cascade>
</many-to-one>
</attributes>
</entity>
<entity class-name="@Department" name="Department" >
<attributes>
<id name="number" type="int"/>
<basic name="name" type="java.lang.String"/>
<version name="ver" type="int"/>
<one-to-many
name="employees"
target-entity="@Employee"
fetch="LAZY"
mapped-by="department">
<cascade><cascade-all/></cascade>
</one-to-many>
</attributes>
</entity>
Beachten Sie, dass jede der vorherigen Entitäten ein Element <id> hat. Für eine klassenlose Entität muss mindestens ein Element <id> oder eine Assoziation mit einem einzelnen Wert definiert werden, die den Schlüssel für die Entität darstellt. Die Felder der Entität werden mit <basic>-Elementen dargestellt. Die Elemente <id>, <version> und <basic> erfordern in klassenlosen Entitäten einen Namen und einen Typ. Einzelheiten zu den unterstützten Typen finden Sie im folgenden Abschnitt zu den unterstützten Attributtypen.
Der Zugriff auf den persistenten Zustand einer Entität durch Clients und EntityManager erfolgt über Felder (Instanzvariablen) oder Zugriffsmethoden, die mit Enterprise-JavaBeans-Eigenschaften angegeben werden. Jede Entität muss den feld- oder eigenschaftsbasierten Zugriff definieren. Annotierte Entitäten sind Entitäten mit Feldzugriff, weil die Klassenfelder annotiert sind, und Entitäten mit Eigenschaftszugriff, wenn die Getter-Methode der Eigenschaft annotiert ist. Eine Mischung von Feld- und Eigenschaftszugriff ist nicht zulässig. Wenn der Typ nicht automatisch bestimmt werden kann, kann das Attribut accessType in der Annotation @Entity oder eine funktional entsprechende XML verwendet werden, um den Zugriffstyp zu identifizieren.
Serialisierbare Attribute werden in der XML-Entitätsdeskriptordatei mit dem Klassennamen des Objekts dargestellt. Wenn das Objekt eine Feldgruppe (Array) ist, wird der Datentyp im Java-internen Format dargestellt. Wenn ein Attribut den Datentyp java.lang.Byte[][] hat, ist die Zeichenfolgedarstellung [[Ljava.lang.Byte;
Vom Benutzer serialisierbare Typen müssen die folgenden bewährten Verfahren einhalten:
Das eXtreme-Scale-Grid ist ein Datencache und erzwingt keine referenzielle Integrität wie eine Datenbank. Obwohl Beziehungen die Operationen "cascading persist" und "remove" für untergeordnete Entitäten zulassen, werden keine fehlerhaften Verknüpfungen mit Objekten erkannt oder umgesetzt. Wenn ein untergeordnetes Objekt entfernt wird, muss die Referenz auf dieses Objekt aus dem übergeordneten Objekt entfernt werden.
Wenn Sie eine bidirektionale Assoziation zwischen zwei Entitäten definieren, müssen Sie den Eigner der Beziehung angeben. In einer :N-Assoziation ist die N-Seite der Beziehung immer der Eigner. Wenn der Eigner nicht automatisch bestimmt werden kann, muss das Attribut mappedBy der Annotation bzw. das funktional entsprechende XML-Element angegeben werden. Das Attribut mappedBy gibt das Feld in der Zielentität an, das Eigner der Beziehung ist. Über diese Attribut können auch die zugehörigen Felder ermittelt werden, wenn es mehrere Attribute mit demselben Typ und derselben Kardinalität gibt.Assoziation mit einem einzelnen Wert
1:1- und N:1-Assoziationen werden mit den Annotationen "@OneToOne" bzw. "@ManyToOne" oder funktional entsprechenden XML-Attributen gekennzeichnet. Der Typ der Zielentität wird über den Attributtyp bestimmt. Das folgende Beispiel definiert eine unidirektionale Assoziation zwischen Person und Address. Die Entität "Customer" hat eine Referenz auf eine einzige Entität, die Entität "Address". In diesem Fall könnte die Assoziation auch eine n:1-Assoziation sein, das es keine Umkehrbeziehung gibt.@Entity
public class Customer {
@Id id;
@OneToOne Address homeAddress;
}
@Entity
public class Address {
@Id id
@Basic String city;
}
Wenn Sie eine bidirektionale Beziehung zwischen den Klassen
"Customer" und "Address" angeben möchten, fügen Sie der Klasse "Customer" über die Klasse "Address" eine Referenz hinzu, und
fügen Sie anschließend die entsprechende Annotation hinzu, um die Gegenseite der Beziehung zu kennzeichnen.
Da diese Assoziation eine 1:1-Assoziation ist, müssen Sie einen Eigner für die Beziehung
mit dem Attribut "mappedBy" in der Annotation "@OneToOne" angeben.@Entity
public class Address {
@Id id
@Basic String city;
@OneToOne(mappedBy="homeAddress") Customer customer;
}
Assoziationen mit Wertesammlungen
1:n- und n:n-Assoziationen werden mit den Annotationen @OneToMany und @ManyToMany oder funktional entsprechenden XML-Attributen gekennzeichnet. Alle Viele-Beziehungen (oder n-Beziehungen) werden mit den Typen java.util.Collection, java.util.List oder java.util.Set dargestellt. Der Typ der Zielentität wird über den generischen Typ des Collection-, List- oder Set-Objekt oder explizit mit dem Attribut targetEntity in der Annotation @OneToMany bzw. @ManyToMany (oder den funktional entsprechenden XML-Elementen) bestimmt.@Entity
public class Customer {
@Id id;
@ManyToOne Address homeAddress;
@ManyToOne Address workAddress;
}
@Entity
public class Address {
@Id id
@Basic String city;
@OneToMany(mappedBy="homeAddress") Collection<Customer> homeCustomers;
@OneToMany(mappedBy="workAddress", targetEntity=Customer.class)
Collection workCustomers;
}
In diesem Beispiel existieren zwei verschiedene Beziehungen zwischen denselben Entitäten:
eine Adressbeziehung "Home" und eine Adressbeziehung "Work".
Es wird ein nicht generisches Collection-Objekt für das Attribut workCustomers
verwendet, um zu veranschaulichen, wie das Attribut targetEntity verwendet wird,
wenn kein generisches Objekt vorhanden ist.Klassenlose Assoziationen
Klassenlose Entitätsassoziationen werden ähnlich wie klassenbasierte Assoziationen in der XML-Deskriptordatei für die Entitätsmetadaten definiert. Der einzige Unterschied ist der, dass die Zielentität nicht auf eine echte Klasse zeigt, sondern auf die Kennung der klassenlosen Entität, die als Klassenname der Entität verwendet wird.
Es folgt ein Beispiel:
<many-to-one name="department" target-entity="@Department" fetch="EAGER">
<cascade><cascade-all/></cascade>
</many-to-one>
<one-to-many name="employees" target-entity="@Employee" fetch="LAZY">
<cascade><cascade-all/></cascade>
</one-to-many>
@Entity
@IdClass(CustomerKey.class)
public class Customer {
@Id @ManyToOne Zone zone;
@Id int custId;
String name;
...
}
@Entity
public class Zone{
@Id String zoneCode;
String name;
}
public class CustomerKey {
Zone zone;
int custId;
public int hashCode() {...}
public boolean equals(Object o) {...}
}
Klassenlose Primärschlüssel
Klassenlose Entitäten müssen mindestens ein Element <id> oder eine Assoziation in der XML-Datei mit dem Attribut id=true haben. Im Folgenden sehen Sie Beispiele für beide Fälle:
<id name="serialNumber" type="int"/>
<many-to-one name="department" target-entity="@Department" id="true">
<cascade><cascade-all/></cascade>
</many-to-one>
Proxys und Feld-Interceptor werden verwendet, um dem EntityManager zu ermöglichen, den Status der Entität zu verfolgen, zu bestimmen, ob sich die Entität geändert hat und die Leistung zu verbessern. Feld-Interceptor sind nur in Plattformen des Typs Java SE 5 verfügbar, wenn der Instrumentierungsagent für Entitäten konfiguriert ist.