1 Themenübersicht
In diesem Dokument lesen Sie, wie vom Kernel für Business Objects und Parts eine oder mehrere Java-Klassen generiert werden. Hinsichtlich dieser Codegenerierung erfahren Sie die Gemeinsamkeiten von Business Objects und Parts sowie ihre jeweiligen Besonderheiten.
2 Zielgruppe
- Entwickler
3 Voraussetzungen
Kenntnisse über den Persistenzdienst werden vorausgesetzt.
4 Begriffsbestimmung
Der Persistenzdienst arbeitet ausschließlich mit „nicht transienten“ Objekten. Wenn der Persistenzdienst ein Objekt von der Datenbank lädt, dann ist dieses Objekt „nicht transient“ und „persistent“.
Wenn ein Objekt vom Persistenzdienst neu generiert wird und noch nicht auf der Datenbank gespeichert ist, dann ist dieses Objekt „nicht transient“ und „nicht persistent“.
Von jedem Objekt kann unabhängig von dessen Zustand eine transiente Kopie angelegt werden. So enthält zum Beispiel eine transiente Kopie eines persistenten Objektes auch die Information, dass das Objekt persistent ist, jedoch fehlt der Bezug auf die Datenbank.
Nicht persistente Objekte
Nicht persistente Objekte sind noch nicht auf einer Datenbank gespeichert.
Nicht transiente Objekte
Nicht transiente Objekte besitzen einen Transaktionskontext und haben damit einen Bezug zu einer Datenbank. Vom Object Manager neu generierte Objekte sind nicht persistent und nicht transient.
Persistente Objekte
Persistente Objekte sind auf einer Datenbank gespeichert und werden von dort aus geladen.
Transiente Objekte
Transiente Objekte sind ohne Transaktionskontext und damit auch ohne Bezug auf eine Datenbank. Die transiente Kopie eines persistenten Objektes enthält die Information, dass das Objekt persistent ist, jedoch fehlt der Datenbankbezug.
5 Gemeinsamkeiten von Business Objects und Parts
Business Objects und veränderbare (mutable) Parts erben ihre Eigenschaften, Methoden und Objekte von der Klasse com.cisag.pgm.datatype.CisObject.
Nicht veränderbare (immutable) Parts erben ihre Eigenschaften, Methoden und Objekte von der Klasse com.cisag.pgm.datatype.CisPart. Diese Klasse ist ein Wrapper (Hülle) um einen veränderbaren Part. Nur ein veränderbarer Part speichert den Inhalt eines Parts.
Business Objects und veränderbare Parts haben, unter anderem aufgrund der identischen Basisklasse, einige Gemeinsamkeiten, die im Folgenden beschrieben werden.
Dadurch, dass veränderbare Parts und Business Objects die gleiche Basisklasse besitzen, existieren Methoden, die zwar in der Basisklasse deklariert sind, aber nicht in der abgeleiteten Klasse überschrieben werden. Diese Methoden wie z. B. getMutableCopy() eines Business Objects, lösen beim Aufruf Ausnahmen (Unsupported Operation Exception) aus. Prüfen Sie deshalb die implementierten Methoden vor ihrem Einsatz. Nutzen Sie dazu den Verwendungskontext oder fragen Sie die Objekttypen ab.
5.1.1 Abfrage der Metadaten
In der Klasse CisObject können Sie den Typ des vorliegenden Objekts nur mit dieser Methode abfragen:
public short get_type();
Der Rückgabewert dieser Methode entspricht je nach Typ des Objekts einer der folgenden Konstanten:
- T_BUSINESS_OBJECT
- T_MUTABLE_PART
- T_VIEW
- T_BUSINESS_ENTITY
- T_BUSINESS_SUBENTITY
Wenn Sie ein Objekt von einem bestimmten Typ überprüfen, dann nutzen Sie die folgende Methode:
public boolean is_type(short type)
Diese Methode berücksichtigt die Abhängigkeiten zwischen den Typen, sie erkennt also Business Entitys und Business-Sub-Entitys auch als Business Objects.
Die GUID (Globally Unique Identifier) des Entwicklungsobjekts Business Object, welches die Basis für die Erzeugung der Klasse ist, kann mit der folgenden Methode abgefragt werden:
public byte[] get_classGuid()
5.1.2 Flags für transient und persistent
Mit den folgenden Methoden können Sie überprüfen, ob das Objekt persistent oder transient ist:
public boolean is_persistent()
public boolean is_transient()
Das Persistent-Flag kann bei transienten Objekten durch diese Methode gesetzt werden:
public boolean set_persistent (boolean value)
Hinweis:
Wird das Flag bei nicht transienten Objekten gesetzt, dann führt diese Methode zu einem Laufzeitfehler.
Mit der Methode
public boolean is_newObject()
prüfen Sie, ob das Objekt bereits am Object-Manager registriert ist. Ein Objekt ist nur dann neu, wenn es mit READ_WRITE bzw. INSERT erzeugt und noch nicht mit putObject an den Object-Manager übergeben worden ist.
5.1.3 Copy-Methoden
Der Inhalt eines Objekts wird durch folgende Methode in eine andere Instanz (der gleichen Klasse oder einer abgeleiteten) kopiert:
public void copyTo(CisObject obj)
Bei zeitabhängigen Objekten wird der Eintrag für das Gültigkeitsintervall nicht mitkopiert.
Wenn das Zielobjekt transient ist, dann wird der vollständige Inhalt des Quellobjekts in das Zielobjekt kopiert, inklusive der Flags „persistent“ und „deleted“.
Wenn das Zielobjekt nicht transient ist, dann wird weder der Primärschlüssel noch ein anderes Flag in das Zielobjekt kopiert.
5.1.4 Equals-Methoden
Den Inhalt von zwei Objekten können Sie mit dieser Methode vergleichen:
boolean contentEquals(Object obj)
Die folgende Equals-Methode nutzen Sie für Business Objects und Parts:
boolean equals(Object object)
Die Methode führt zu unterschiedlichen Ergebnissen:
- Bei Business Objects wird der Primärschlüssel (primary key) und das Flag „transient“ verglichen.
- Bei Parts wird die folgende Methode aufgerufen:
contentEquals
5.1.5 Serialisierung
Der Zustand eines Objektes kann in einem Byte-Array serialisiert werden. Die Serialisierung liefert eine vollständige Kopie des Inhalts eines Objekts. Dadurch werden auch in einem Objekt enthaltene Parts und Arrays kopiert.
Geben Sie für die Serialisierung an, ob Sie das vollständige Objekt (changesOnly=false) oder nur Teile des Objekts serialisieren möchten. Die Teile des Objekts beziehen sich dann nur auf die in der aktuellen Transaktion veränderten Teile. Serialisieren Sie das Objekt oder Teile davon mit der Methode:
public byte[] serialize(boolean changesOnly)
Hinweis:
Nutzen Sie aus Übersichtlichkeitsgründen ausschließlich die Serialisierung eines vollständigen Objektes.
5.1.6 Deserialisierung
Ein serialisiertes Objekt kann auf zwei Arten deserialisiert werden:
- Sie kopieren den Inhalt des Byte-Arrays in eine vorhandene Instanz der gleichen Klasse. So wird also der Inhalt eines zuvor serialisierten Objektes in eine vorhandene Instanz geschrieben. Nutzen Sie dazu diese Methode:
public void deserialize (byte[]array)
Sie ähnelt der Methode copyTo, jedoch enthält das serialisierte Byte-Array auch die Gültigkeitsbereiche der zeitabhängigen Objekte.
- Sie generieren mit dem Inhalt des Byte-Arrays eine neue Instanz. Die Instanz der serialisierten Klasse generieren Sie mit dieser Methode:
public static CisObject create NewInstance (byte[]array)
5.2 Parts
In diesem Abschnitt werden die Methoden beschrieben, die nur bei mutablen Parts implementiert sind.
5.2.1 Copy-Methoden
Die folgende Methode erstellt eine „Tiefe Kopie“ des Parts:
public CisObject copy()
Hinweis:
Der Begriff „Tiefe Kopie“ bezeichnet eine vollständige Kopie eines Parts mit allen darin enthaltenen Attributen und Parts. Der gesamte Inhalt eines Parts wird kopiert.
5.2.2 Zugriff auf immutable (unveränderliche) Parts
Ein immutabler Part ist eine Hülle (Wrapper) um einen mutablen Part. Wenn Sie einen mutablen Part in einen immutablen Part umwandeln, dann stehen Ihnen zwei Vorgehensweisen zur Auswahl:
- Sie generieren einen neuen Wrapper um den existierenden mutablen Part:
- public CisPart castImmutable()
- public static <<Part>> castImmutable(<<PartMutable>> partMutable)
- public static <<Part>>[] castImmutable(<<PartMutable>>[] partMutable)
- Sie generieren eine Tiefe Kopie des mutablen Parts:
- public CisPart getImmutableCopy ()
- public static <<Part>> getImmutableCopy (<<PartMutable>> partMutable)
- public static <<Part>> getImmutableCopy (<<PartMutable>>partMutable)
Die static-Methoden prüfen jeweils vorab, ob das Argument null ist. Ist das Argument null, dann ist das Ergebnis dieser Methoden null.
Unterschiede
- castImmutable
Mit castImmutable wird keine Kopie erzeugt. Deshalb ändern sich gegebenenfalls die Attribute des immutablen Parts, wenn der mutable Part geändert wird.
- copyImmutable
Der immutable Part wird in einem eigenen mutablen Part gespeichert. Der immutable Part kapselt einen mutablen Part. Daher kann kein Programm einen immutablen Part verändern.
5.2.3 Zugriff auf mutable Parts
Der mutable Part ist von einem immutablen Part eingeschlossen. Wurde der immutable Part generiert, dann kann auf den mutablen Part nicht mehr zugegriffen werden. Deshalb kann nur eine Kopie eines mutablen Parts generiert werden, die den Inhalt des immutablen Parts enthält. Folgende Methoden generieren mutable Parts:
public CisObject getMutableCopy()
public static <<PartMutable>> getMutableCopy (<<Part>> part)
public static <<PartMutable>>[] getMutableCopy (<<Part>>[] part)
Die static-Methoden prüfen jeweils vorab, ob das Argument null ist. Ist das Argument null, dann ist das Ergebnis dieser Methoden null.
5.3 Business Objects
An jeder Business-Object-Instanz kann ein Iterator mit allen existierenden Instanzen mit den folgenden Methoden abgefragt werden:
public CisObjectIterator retrieve_instances()
public CisObjectIterator retrieve_instances(int flags)
Hinweis:
Objekt-Referenzen dürfen in Semiramis 4 nicht mehr verwendet werden. In Business Objects die in Semiramis R2 angelegt wurden, können jedoch noch Objekt-Referenzen enthalten. Diese Business Objects sollten jedoch sobald als möglich umgestellt werden, da zukünftig Objekt-Referenzen nicht mehr unterstützt werden.
Die Objekt-Referenz auf ein Business Object wird mit dieser Methode abgefragt:
byte[] get_objectReference()
Eine Objektreferenz kann nur bei persistenten Business Objects abgefragt werden. Die abgefragte Objekt-Referenz wird in einem Business Object geladen. Sie ist nur dann gültig, wenn die Transaktion mit der Anweisung commit abgeschlossen wurde.
5.3.1 Keys
Alle Business Objects haben statische Methoden, mit denen sich die verschiedenen Keys generieren lassen. Auch Keys von (noch) nicht existierenden Business Objects können damit erzeugt werden. Die statischen Methoden zum Generieren eines Keys befinden sich in der Klasse des Business Object zu dem der Key gehört. Sie haben folgenden Aufbau:
<<BusinessObject>>.build<<KeyName>>Key(<<KeyAttribute 1>>,…,<<KeyAttribute n>>)
Beim Primärschlüssel beginnt der Schlüsselname immer mit Primary, d. h. der Primärschlüssel kann immer mit der folgenden Methode am Business Object erzeugt werden:
buildPrimaryKey
Der Primärschlüssel einer Instanz eines Business Object kann an der Instanz mit dieser Methode abgefragt werden:
public byte[] get_primaryKey()
Alle eindeutigen Schlüssel (Unique-Keys), also die Primär- (primary key), die Sekundär- (secondary key) und die Business-Schlüssel (business key), können mit folgender Methode abgefragt werden:
public byte[][] get_uniqueKeys()
Der Instance String ist eine Zeichenkette, die eine Instanz eines Business Object für den Benutzer verständlich identifiziert, z. B. „Artikel 4711–Radioempfänger“. Die in dem Instance String verwendeten Attribute finden sich in dem Business Key wieder. Nutzen Sie für die Abfrage folgende Methode:
public String get_instanceString()
Sobald eine Business-Object-Instanz das erste Mal mit putObject an den Object-Manager übergeben wurde, können die Primärschlüsselattribute nicht der Business Object Instanz nicht mehr verändert werden.
5.3.2 Beziehungen
Zwischen Business Objects und von Part zu Business Objects können Beziehungen existieren. Dabei werden 1:1 und 1:n Beziehungen unterschieden. Für jede Beziehung wird eine retrieve-Methode an dem Objekt generiert, von dem die Beziehung ausgeht. Mit der retrieve-Methode können die referenzierten Business-Objects abgefragt werden. Wenn die Objekte NLS-Attribute enthalten werden die referenzierten Objekte wie folgt geladen:
- Bei Business Objects werden die referenzierten Objekte in der Sprache geladen, in der das Quellobjekt geladen wurde.
- Bei Parts werden die referenzierten Objekte in der Datenbanksprache geladen.
Die retrieve-Methoden für 1:1 Beziehung werden wie folgt generiert:
<<BusinessObject>> retrieve<<Beziehungsname>>()
<<BusinessObject>> retrieve<<Beziehungsname>>(int flags)
Die retrieve-Methoden für 1:n Beziehung werden wie folgt generiert:
CisObjectIterator retrieve<<Beziehungsname>>()
CisObjectIterator retrieve<<Beziehungsname>>(int flags)
Der optionale Parameter flags gibt an, wie das Objekt geladen werden soll. Die entsprechenden Konstanten (READ, READ_UPDATE, …) finden Sie am Object-Manager.
5.3.3 Copy-Methoden
Jedes persistente Business Object ist nur innerhalb der Transaktion gültig, in der es vom Object Manager geladen wurde. Wenn Sie ein Business Object verwenden, das von keiner Transaktion abhängig ist, dann müssen Sie mit den nachfolgenden Methoden eine transiente Kopie des Business Object generieren:
public static <<BusinessObject>> getTransientCopy(<<BusinessObject>> object)
public static << BusinessObject>> getTransientCopy(<<BusinessObject>> object)
public static << BusinessObject>>[] getTransientCopy(<<BusinessObject>>[] object)
Die static-Methoden prüfen jeweils vorab, ob das Argument null ist. Ist das Argument null, dann ist das Ergebnis dieser Methoden null.
5.3.4 Lokalisierbare Attribute
Zum Zeitpunkt des Ladens eines Business Object können Sie angeben, in welcher Sprache die lokalisierbaren Attribute ausgegeben werden. Die Sprache, in der die lokalisierbaren Attribute geladen wurden, wird mit folgender Methode über das Business Object abgefragt:
public String get_contentLanguage()
5.3.5 Zeitabhängigkeit
Prüfen Sie mit nachfolgender Methode, ob ein Business Object zeitabhängig ist:
boolean is_timeDependent()
Für zeitabhängige Objekte werden unabhängig von der Art der Zeitabhängigkeit die folgenden Methoden generiert:
public java.util.Date getValidFrom()
public void setValidFrom(java.util.Date validFrom)
public java.util.Date getValidUntil()
public void setValidUntil(java.util.Date validUntil)
Das Gültigkeitsintervall [validFrom, validUntil[ eines zeitabhängigen Objekts kann mit diesen Standard-Methoden gelesen oder verändert werden.
Hinweis:
Die Richtung der eckigen Klammern gibt an, ob die Intervallgrenzen im Intervall enthalten sind.
In diesem Fall ist die untere Grenze validFrom im Gültigkeitsintervall enthalten, während die obere Grenze validUntil nicht im Gültigkeitsintervall enthalten ist.
Bei zeitabhängigen Objekten können ggf. mehrere Objekte mit dem gleichen Primär- oder Sekundär-Schlüssel vorkommen, wenn diese disjunkte Gültigkeitsintervalle haben. Der normale Primärschlüssel enthält nicht das Attribut validFrom. Deshalb stehen folgende Methoden zur Verfügung mit denen ein Schlüssel von einem Business Object abgefragt bzw. generiert wird.
Bei Zeitabhängigkeit der Art „Datum mit Zeitzone durch Anwendung“ bzw. „Zeitpunkt mit Zeitzone durch Anwendung“ wird zusätzlich das Attribut _timeZoneGuid generiert. Das Attribut timeZoneGuid hat die gleiche Bedeutung wie bei Object-Dates bzw. -Timestamps. Die Attribute validFrom und validUntil sind jedoch keine CisDates.
Dieser Schlüssel identifiziert das Business Object mit seinem Gültigkeitsintervall:
public byte[] get_timeDependentKey()
public byte[] buildTimeDependentKey(<<PrimaryKey>>, java.util.Date validFrom)
Zu einem zeitabhängigen Objekt kann die zeitlich nächste oder vorhergehende Version eines Business Object mit folgenden Methoden abgefragt werden:
public <<BusinessObject>> retrieve_nextVersion()
public <<BusinessObject>> retrieve_nextVersion(int flags)
public <<BusinessObject>> retrieve_previousVersion()
public <<BusinessObject>> retrieve_previousVersion(int flags)
5.3.6 Änderungs-Informationen
Prüfen Sie mit folgender Methode, ob zu einem Business Object Anwendungs-Informationen gepflegt werden sollen:
boolean is_updateInfoRequired()
Für Objekte mit Änderungs-Informationen werden die folgenden Methoden generiert:
public UpdateInformation getUpdateInfo()
public UpdateInformationMutable getMutableUpdateInfo()
public void setUpdateInfo(UpdateInformationMutable _updateInfoInstance)
Die Änderungs-Informationen eines Objekts können mit diesen Standardmethoden gelesen und verändert werden. Mit der Änderungs-Information erfahren Sie, wann welcher Benutzer das Business Object generiert, zuletzt verändert oder gelöscht hat. Das Löschen bedeutet nicht, dass das Business Object tatsächlich physikalisch auf der Datenbank gelöscht wird. Mit der Methode:
public void set_deleted(boolean value)
wird nur das Lösch-Flag (Löschdatum in Änderungs-Information nicht null) gesetzt. Dadurch kann das Anwendungsprogramm gelöschte Objekte besonders hervorheben. Mit der folgenden Methode kann eine Anwendung abfragen, ob ein Business Object als gelöscht markiert ist:
public boolean is_deleted()
Die Methoden
- is_deleted und
- set_deleted
sind auch bei Objekten verfügbar, die keine Änderungs-Informationen haben. In diesem Fall dürfen diese Methoden jedoch nur bei transienten Objekten benutzt werden.
5.3.7 Business Entitys
Wenn ein Business Object ein Sub-Entity oder ein Dependent ist, dann können Sie mit diesen Methoden das zugehörige Business Entity abfragen:
public CisObject retrieve_entity()
public CisObject retrieve_entity(int flags)
5.3.8 Datum- und Zeitangaben mit Zeitzone
Zeit- und Datumsangaben mit Zeitzone werden in der Java-Klasse com.cisag.pgm.datatype.CisDate gespeichert. Ein CisDate besteht aus einem Zeitpunkt und einer Zeitzone. In dem Namensraum com.cisag.pgm.datatype befinden sich diverse Datentypen, um ein CisDate-Attribut in einem Business Object oder Part zu verwenden. In der Codegenerierung unterscheiden sich dabei CisObjectDate bzw. CisObjectTimeStamp und CisAttributDate bzw.
CisAttributeTimeStamp.
Alle CisObjectDates in einem Business Object müssen die gleiche Zeitzone haben. Die Zeitzone der CisObjectDates wird in dem Attribut timeZoneGuid gespeichert. Das Attribut timeZoneGuid kann nur bei der Neuanlage des Business Objects gesetzt werden. Nachdem das Attribut einmal gesetzt wurde, kann dieses bei nicht transienten Objekten nicht mehr verändert werden, jedes weitere setzen des Attributs führt zu einem Laufzeitfehler:
- Wenn in Parts CisObjectDates verwendet werden, dann wird die Zeitzone erst geprüft, wenn eine Part-Instanz in einen Business-Object-Attribut gesetzt wird.
- Wenn ein CisDate mit einer abweichenden Zeitzone in eine CisObjectDate Attribute gesetzt wird, kommt es zu einem Laufzeitfehler.
5.3.9 Hauswährungen
Wenn in einem Business Object Hauswährungen (DomesticAmounts) verwendet werden, dann werden zusätzliche Attribute an das Business Object generiert:
- _organization (GUID)
Die Guid der Organisationseinheit auf die sich alle Hauswährungen in dem Business Object bei der Konvertierung beziehen.
- _conversionDate (TimeStamp)
Der Zeitpunkt der Konvertierung.
- _currecyCombo (short)
Die Währungskombination
Diese Attribute werden insbesondere beim Reorganisieren der Organsationseinheiten bzw. beim Ändern der Währungskombinationen verwendet.