Datenbankänderungen

1                     Zielgruppe

Jeder Entwickler, der Änderungen am Datenbankschema vornimmt, muss mit der prinzipiellen Funktionsweise der Generierungstools vertraut sein.

2                     Voraussetzungen

Zum Verständnis dieses Dokuments ist ein Verständnis der Grundlagen des Persistenzdienstes notwendig. Detaillierte Informationen zum Persistenzdienst finden Sie in der Dokumentation „Persistenzdienst“.

3                     Beschreibung

Datenmodelländerungen an Business Objects müssen gut geplant sein, da fehlerhaft durchgeführte Datenmodelländerungen zu Datenverlusten beim Kunden führen können. Datenmodelländerungen sollen auf dem Produktivsystem so schnell wie möglich ausgeführt werden.

Die Update-Klasse enthält die Regeln und Algorithmen, um die Aufgaben bei einer Datenmodelländerung erfüllen zu können. Die Update-Klasse beschränkt sich dabei auf die Kernaufgaben, d.h. auf die Operationen auf den Spalten eines Business Objects wie Initialisierungen und Änderungen. Die Update-Klasse enthält also für jede geänderte Spalte eines Business Objects die Information, wie die Änderung pro Spalte behandelt werden soll.

Die Update-Klasse wird initial bei der ersten Änderung bzw. Neuanlage des Business Objects erzeugt. Bei späteren Änderungen werden entsprechende Methoden hinzugefügt. Diese können bzw. müssen vom Entwickler geändert werden. Die Generierung selbst löscht niemals Methoden oder Variablen aus den Update-Klassen. Sie fügt nur bei Bedarf neue Methoden hinzu.

Eine Update-Klasse darf nur auf dem System geändert werden, auf dem das zugehörige Business Object bzw. die Extension entstanden ist oder geändert wurde. Dadurch wird verhindert, das ein Konflikt auf dieser Klasse beim Einspielen einer Softwareaktualisierung, welche diese Klasse enthält, entsteht und das zugehörige Business Object mit der adaptierten Klasse anstatt der Klasse aus der Softwareaktualisierung konvertiert wird.

 

Für jedes Business Object und jede Extension gibt es separate Update-Klassen. Jede der Update-Klassen ist für die Attribute des zugeordneten Objektes zuständig. Damit entstehen keine manuell zu bearbeitenden Konflikte, falls beispielsweise ein Standard Business Object durch eine Extension erweitert wird. Die Update-Klassen werden im Namensraum „com.<Entwicklungspräfix>.upd“ abgelegt, z. B. „com.cisag.upd.app…“ oder „com.cisag.upd.sys…“.

Die Update-Klassen implementieren jeweils die Logik, um die persistenten Daten eines Business Objects oder einer Extension einer beliebigen Quellversion in die aktuelle Zielversion zu transformieren.

Datenmodelländerungen werden für jede Spalte einzeln betrachtet. Bei der normalen Bearbeitung werden alle Änderungen von Spalten mit einem Standardverhalten registriert, dass vom Entwickler überschrieben werden kann. Der Unterschied zwischen dem Quell-Schema und dem Ziel-Schema bestimmt, welche der Methoden zur Anwendungen kommen.

Die Update-Klassen unterstützen die folgenden Operationen:

Beispiel für Update-Klassen

Dieses Beispiel soll die Funktionsweise der Update-Klassen erklären. Die Änderungen im Business Object sowie die verwendeten Methoden der Update-Klassen sind in fetter Schrift angegeben.

Beispiel Standard

 

Beispiel für Update-Klassen bei Änderungen im Standard

Im obigen Beispiel wird das Business Object Item zweimal verändert. Als erstes wird das Attribut description von 100 auf 80 Zeichen verkürzt und danach das Attribut unit hinzugefügt.

  • Die Methode changeDatatype€description€str100_str80 berechnet die inkompatible Datentypänderung des Attributs description von 100 auf 80 Zeichen.
  • Die Methode init€unit berechnet den Initialwert für das neue Attribut unit.

Die Methoden werden beim Ausführen der Datenmodelländerung aufgerufen.

Beispiel Partnerentwicklung

 

Anlegen einer Extension und Einspielen von einer Standard-Erweiterung

Zunächst wird eine Extension für das Business Object Item mit den Attributen abc_type und abc_color angelegt und danach wird die Version 1.1 von Item eingespielt. Sie müssen bei einer Extension keine manuelle Konfliktbearbeitung auf den Update-Klassen des Business Objects vornehmen.

  • Die Methode init€abc_type berechnet den Initialwert für die Spalte abc_type.
  • Die Methode init€abc_color berechnet den Initialwert für die Spalte abc_color.

Bei der Anlage der Extension werden die Methoden der Update-Klassen der Extension aufgerufen. Bei der Änderung des zugrunde liegenden Business Objects Item, müssen die Update-Klassen nicht verändert werden und es werden keine Methoden von der Update-Klasse der Extension aufgerufen.

Beispiel Kundenentwicklung

 

Extension mit Part in Kundenadaptierung

Analog zu dem Partnerentwicklungssystem ist auch im Kundenadaptierungssystem keine manuelle Konfliktbearbeitung auf den Update-Klassen des Business Objects oder der Business Object Extensions vom Partnerentwicklungssystem erforderlich. Mit der Business Object Extension XYZ_Item werden die Partattribute xyz_coordinate mit dem Part Coordinate und xyz_length mit dem Part Quantity hinzugefügt.

  • Die Methode init€xyz_length berechnet den Initialwert der Spalten des partwertigen Attributes xyz_length.

Das Part com.cisag.app.general.obj.Quantity wird von den Update-Klassen als Ganzes behandelt, daher kann das Part als Ganzes initialisiert werden und es gibt nur eine Init-Methode (siehe Abschnitt „Datentypen“).

  • Die Methoden init€xyz_coordinate…€… berechnen die Initialwerte der Spalten des partwertigen Attributs xyz_coordinate.

Für das Part Coordinate gibt es keine Spezialbehandlung, alle Spalten müssen einzeln initialisiert werden und haben separate Init-Methoden (siehe Abschnitt „Datentypen“).

3.1               Datenmodelländerung

Der Ablauf einer Datenmodelländerung hängt davon ab, wie die Daten von der Quell- in die Zielversion überführt werden sollen.

Die Generierung eines Business Objects während der Entwicklung läuft in den folgenden Schritten ab:

Ablauf einer Datenmodelländerung im Entwicklungssystem

Nach dem ein Business Object, View oder Part in der Anwendung „Entwicklungsobjekte“ bearbeitet wurde, muss dieses mit dem Tool crtbo generiert werden. Dabei werden die Java-Sourcen für die Mapper- und Update-Klassen sowie die temporären Tabellen erzeugt. Danach müssen ggf. die Update-Klassen vom Entwickler angepasst werden. Mit den geänderten Update-Klassen können dann die Daten testweise in die temporären Tabellen konvertiert werden. Der Application-Server des Entwicklers greift auf die temporären Tabellen zu (siehe nächster Abschnitt) und damit kann der Entwickler testen, ob die Konvertierung erfolgreich war. Wenn der Entwickler die Entwicklungsaufgabe freigegeben hat, so werden die Daten noch mal konvertiert und die Änderung auf allen Datenbanken aktiviert. Nach dem Aktivieren der Datenmodelländerung kann die Entwicklungsaufgabe aktiviert werden.

Datenmodelländerungen bilden meist mit Änderungen am verarbeitenden Quellcode eine Einheit. Sie können die Konsequenzen einer Schemaänderung testen, bevor die Schemaänderung aktiviert wird und damit ggf. andere Nutzer des Systems behindert. Die in der aktuellen Entwicklungsaufgabe erzeugten neuen Mapper greifen auf die temporäre Tabelle mit dem neuen Schema mit den konvertierten Daten zu, während die alten (im System aktiven Mapper) noch auf die bisher aktiven Tabellen im alten Schema zugreifen.

Beispiel für den Zustand beim Entwickeln einer Datenmodelländerung

Beachten Sie, dass nur für die Business Objects temporäre Tabellen erzeugt werden, die in der Entwicklungsaufgabe gesperrt sind und dort generiert wurden. Auf diese Tabellen kann standardmäßig nur lesend zugegriffen werden. Deswegen kann eine Anwendung nur eingeschränkt getestet werden. Über den Application-Server-Startparameter „-writeConvertedTables“ kann der Schreibzugriff auf die temporären Tabellen aktiviert werden. Prüfen Sie die Verwendung gründlich, da die möglichen Seiteneffekte schwer überschaubar sind.

Beispiel:

Sie haben z.B. ein Entity in der Entwicklungsaufgabe gesperrt und dessen Dependents nicht. Wenn Sie nun eine neue Instanz des Entities anlegen, wird die Entitiy-Instanz in die temporäre Tabelle geschrieben, während die Dependents der Instanz in die aktiven Tabellen geschrieben werden. Alle anderen Nutzer würden mit den alten noch aktiven Mappern neue Entities nur in aktiven Tabellen schreiben. D. h., man erzeugt sich inkonsistente Zustände in der Datenbank. Ähnliche Probleme können auch bei Nummernkreisen und Zählern auftreten.

Um die Daten in der temporären Tabelle über die Anwendung „OQL-Anweisungen“ abzufragen, muss das Schlüsselwort CONVERTED_TABLE zwischen        Business Object-Name und Aliasname angegeben werden. Zum Zugriff auf die aktive Tabelle dient das Schlüsselwort ACTIVE_TABLE.

Die neuen Tabellen können nur dann aktiviert werden, wenn die Entwicklungsaufgabe freigegeben und noch nicht aktiviert ist. Die Änderungen an der Datenbank haben erst bei der Aktivierung eine Auswirkung auf die anderen Nutzer des Systems. Nach der Aktivierung eines Business Objects oder Views sollten alle Server, die auf dieses Business Object zugreifen, neu gestartet werden.

3.2               Generischer Zugriff auf Business Objects

In den Update-Klassen kann mit den normalen Business Object Mappern nicht auf Business Objects zugegriffen werden. Alle Business Objects werden mit generischen Mappern gelesen. Dieser Abschnitt beschreibt den generischen Zugriff auf Business Objects.

3.2.1          Objekt-Schema

Jedes Business Object wird vollständig durch Metadaten beschrieben. Die Schema-Metadaten eines Business Objects können als com.cisag.pgm.appserver.CisObjectSchema am CisObjectManager abgefragt werden. In den Update-Klassen kann das Quell- und Zielschema der Datenmodelländerung mit den Methoden CisUpdateBase:getFromSchema und CisUpdateBase:getToSchema abgefragt werden.

Das Schema enthält unter anderem die Beschreibung aller Spalten des Business Objects. Die Spaltenbeschreibung kann mit den Methoden CisObjectSchema:getColumn und CisObjectSchema:getColumns am Schema abgefragt werden.

Hinweis

Mit dem Schema und dem Abfragen der Spaltenbeschreibung können Sie prüfen, ob bei einer Datenmodelländerung im Quellschema bereits eine bestimmte Spalte existiert.

3.2.2          Generischer Zugriff

Der Persistenzdienst greift normalerweise über generierte Business Object Mapper auf Business Objects zu. Die Mapper müssen exakt zu der auf der Datenbank generierten Tabelle passen, ansonsten können die Daten nicht ohne Fehler gelesen und geschrieben werden. Für die historischen Versionen eines Business Objects liegen diese Mapper nicht mehr vor.

Die Klasse com.cisag.pgm.datatype.CisGenericObject erlaubt einen generischen Zugriff auf beliebige Versionen eines Business Objects. Die Update-Klassen verwenden diese generischen Objekte für Datenmodelländerungen. Jeder Persistenzdienstzugriff, z.B. getObject, der ansonsten eine Business Object Instanz liefern würde, liefert in den Update-Klassen ein generisches Objekt.

Beim generischen Zugriff auf Business Objects können Sie alle Zugriffsmethoden des Object-Managers verwenden, d.h. getObject, getObjectIterator, getResultSet, …. Der Object-Manager greift dabei immer auf die auf der Datenbank aktive Version des Business Objects zu. Sie können mit dem generischen Zugriff auf den Zustand der Datenbank vor der Datenmodelländerung zugreifen. Auf das Ergebnis der Datentransformation können Sie mit dem generischen Zugriff nicht zugreifen. Sie können keine Methoden des Objektmanagers verwenden, die zum Schreiben auf die Datenbank dienen, es kann ausschließlich von der Datenbank gelesen werden.

Die Spalten eines generischen Business Objects können über den Attributpfad abgefragt werden. Für jeden primitiven Datentyp sowie für die Special Parts existieren geeignete Get- und Set-Methoden.

Um zu ermitteln, ob für eine Spalte eines Part-Attributs ein gültiger Wert abgefragt werden kann, muss die Abfrage der boolschen Spalte des Part-Attributs wahr liefern. Der Name dieser Spalte ist der Attributpfad des Part-Attributs.

Mit der Methode buildPrimaryKey kann der Primärschlüssel oder der zeitabhängigen Primärschlüssel eines Business Objects erzeugt werden.

Beispiel

Beispiel für die Verwendung eines CisGenericObjects mit dem CisObjectManager:

CisGenericObject item = (CisGenericObject)om.getObject(

CisGenericObject.buildPrimaryKey(

“com.cisag.app.general.obj.Item“,itemGuid)

oldDescription=item.getString(”description“);

Es ist zu beachten, dass die Abfrage eines Datums- oder Zeitstempel-Attributs, dessen logischer Datentyp auf dem logischen Datentyp „com.cisag.sys.kernel.ObjectTimeStamp“ basiert, mit der Methode getTimeStamp() zu erfolgen hat, welche ein java.util.Date-Objekt liefert. Ein evtl. benötigter CisDate-Wert muss selbst erzeugt werden.

Beispiel

Date dateValue = item.getTimeStamp(“purchaseStatusDate”);

Byte[] timeZoneGuid = item.getGuid(“_timeZoneGuid”);

CisDate purchaseStatusDate = com.cisag.pgm.datatype.CisDateUtility.createCisDate(timeZoneGuid, dateValue);

3.2.3          Verwendung von Transaktionen

Vor Aufruf einer Methode einer Updateklasse wird vom System automatisch eine Transaktion für die zu konvertierende Datenbank geöffnet, so dass standardmäßig alle Verwendungen des Objektmanagers den richtigen Transaktionskontext haben. Bei Nutzung der automatisch geöffneten Transaktion kann keine Subtransaktion verwendet werden. Es ist erlaubt, eine weitere Top-Level-Transaktion über die Transaktionsmanager-Methode beginNew(byte[] databaseGuid) zu öffnen. Die übergebene Datenbank-GUID muss die GUID der Datenbank sein, die konvertiert werden soll. Diese muss über die Methode getDatabaseGuid() der Update-Klasse ermittelt werden. Für eine neu erstellte Transaktion können auch Subtransaktionen erzeugt werden.

3.3               Update-Klassen

Die Update-Klassen legen fest, wie die im Quell-Schema gespeicherten Daten in das Ziel-Schema überführt werden sollen. Die Update-Klassen spezifizieren die Datentransformation pro Spalte im Business Object mit Init- und ChangeDatatype-Methoden.

Im Abschnitt „Beschreibung“ wurde die Update-Klasse für Business Objects und Extensions beschrieben. In diesem Abschnitt wird beschrieben, wie der Entwickler eine Datenmodelländerung in dieser Update-Klasse umsetzen kann.

3.3.1          Init-Methode

Die Init-Methode berechnet den Initialwert beim Anlegen einer neuen Spalte. Ein Initialwert wird dann benötigt, wenn eine Spalte im Ziel-Schema existiert, aber nicht im Quell-Schema. Die Init-Methode wird in der Update Klasse mit einem konstanten Initialwert generiert. Die Init-Methode kann in der Update Klasse ggf. geändert werden, um einen abweichenden Initialwert zu berechnen.

Der Name der Init-Methode setzt sich wie folgt zusammen:

<Java-Datatype> init€<AttributePath> ()

Der Attributpfad einer Spalte entspricht dem Namen der Spalte in OQL. Eckige Klammern „[]“ und der Punkt „.“ werden jedoch durch das Dollarzeichen „$“ ersetzt, damit der Attributpfad als Methodenbezeichner verwendet werden kann.

Bespiel:

Wenn der Attributpfad in OQL „discounts[1].discountType“ ist, dann wird im Methodennamen die Zeichenkette „discounts$1$$discountType“ verwendet.

Der Abschnitt „Datentypen“ enthält weitere Informationen zu dem Datentyp im Methodennamen.

Für ein Part-Attribut wird neben den Init-Methoden der zugehörigen Spalten zusätzlich die Init-Methode für die boolsche Spalte des Parts generiert. Diese hat als Attributpfad den Attributpfad des Part-Attributes. Der Rückgabewert der Methode gibt an, ob der Part-Wert gültig ist oder nicht. Um ein Part-Attribut mit einem Wert zu initialisieren, muss die Init-Methode für die boolsche Part-Spalte so überschrieben werden, dass diese true liefert. Die Init-Methode wird in der Klasse Update des Business Objects generiert, falls die Spalte zu einem Attribut des Business Objects gehört. Falls die Spalte zu einem Attribut einer Business Object Extension gehört wird die Init-Methode in der Klasse Update der Business Object Extension generiert.

Beispiel:

Initialwertberechnung der Spalte description mit dem Datentyp String und mit der Länge 100. Update-Klasse, generiert

String init€description () {

return “”;

}

Update-Klasse, angepasst durch Entwickler

String init€description() {

return “Artikel”);

}

3.3.2          Init-Methode bei Wiederanlagen

Eine Wiederanlage einer Spalte liegt beispielsweise dann vor, wenn eine Spalte mit der Version V1 angelegt wurde, mit V2 gelöscht wurde und mit V3 wieder angelegt wird. Technisch gibt es hier keinen Unterschied zu einer Neuanlage, allerdings kann es natürlich sein, dass eine alte Init-Methode noch in der Update-Klasse steht. Der Entwickler hat dies zu überprüfen und evtl. anzupassen. Die Generierung löscht niemals existierende Methoden aus der Update-Klasse.

3.3.3          Init-Methoden bei Part-Attributen

Soll ein Part-Attribut mit einem komplexen Wert initialisiert werden, muss die init()-Methode für die boolsche Spalte des Parts wahr zurückliefern. Damit wird angegeben, dass überhaupt ein Partwert existiert. Der Name dieser Spalte ist der Attributpfad des Part-Attributs. Für alle Spalten des Parts werden passende init()-Methoden erzeugt.

Bei der Neuanlage einer Spalte mit einem Special-Part wird nur eine init()-Methode erzeugt.

3.3.4          ChangeDatatype-Methode

Der Datentyp einer Spalte kann verändert werden. Um den Inhalt einer Spalte vom alten in den neuen Datentyp umzuwandeln, ist eine Berechnung erforderlich. Die Berechnung erfolgt in der ChangeDatatype-Methode, die in der Update-Klasse generiert wird:

<Java-TargetDatatype>

changeDatatype€<AttributePath>€<SourceDatatype>_<TargetDatatype>(

CisGenericObject object)

Eine passende ChangeDatatype-Methode wird erwartet und ausgeführt, wenn während der Konvertierung die Änderung des Datentyps zwischen Quell- und Zielschema festgestellt wird. Sollte der Datentyp einer Spalte mehrfach geändert werden, ist für jede potentiell auftretende Datentypänderung eine entsprechende Methode notwendig. Durch die Generierung wird nur eine Methode für die letzte Datentypänderung auf dem Entwicklungssystem erzeugt. Es obliegt der Verantwortung des Entwicklers evtl. noch fehlende ChangeDatatype Methoden anzulegen. Entsprechend können ChangeDatatype Methoden auch entfernt werden, wenn die entsprechende Schemaänderung noch nicht ausgeliefert wurde. Die Entscheidung hierüber muss ebenfalls durch den Entwickler getroffen werden.

Beispiel:

  • Eine neue Spalte mit Datentyp „boolean“ wird angelegt
  • Der Datentyp wird auf „short“ geändert.
  • Der Datentyp wird ein weiteres Mal geändert, diesmal auf „String“

In solch einer Konstellation würde im zweiten Schritt durch die Generierung eine ChangeDatatype Methode von boolean auf short entstehen. Im dritten Schritt entstünde dann ein ChangeDatatype Methode von short auf String. Sollte die Datenmodelländerung aus dem ersten Schritt bereits ausgeliefert sein, dann müsste der Entwickler noch eine ChangeDatatype Methode von boolean auf String anlegen. Umgekehrt kann er die ChangeDatatype Methoden auch löschen, wenn die Schemaänderungen noch gar nicht ausgeliefert wurden und nur die Initialisierung vom Typ „String“ auf potentiellen Zielsystemen zum Tragen kommen kann.

Eine Datenmodelländerung ist kompatibel, wenn der primitive Datentyp nicht verändert und die Länge des Datentyps vergrößert wird. Alle anderen Änderungen sind inkompatibel.

Beispiel:

Die Änderung von String 80 auf String 100 ist kompatibel.

Die Änderung von String 100 auf String 90 ist inkompatibel.

Die Änderung von Decimal 10,3 auf Decimal 17,6 ist kompatibel.

Die Änderung von Short auf ValueSet ist inkompatibel.

Die Änderung von Boolean auf ValueSet ist inkompatibel.

Wenn die Datentypänderung inkompatibel war, so werden die ChangeDatatype-Methoden in der Klasse Update generiert, aber ohne definierten Rückgabewert. Dies führt gewollt zu einem Compile Fehler und somit müssen sie vom Entwickler implementiert werden. Inkompatible Datenmodelländerungen führen immer zu eine instanzweisen Konvertierung.

Hinweis:

Inkompatible Änderungen erhöhen den Konfliktbearbeitungsaufwand in Folgesystemen. Vermeiden Sie inkompatible Datenmodelländerungen. Bei der parallelen Wartung sind inkompatible Datenmodelländerungen in älteren Releases besonders problematisch (siehe Abschnitt „Parallele Wartung“).

Beispiel:

Update-Klasse

 

String changeDatatype€description€str100_str90(

CisGenericObject object) {

String value = object.getString(“description”);

if (value.length()<=90) {

return value;

} else {

return value.substring(0,87)+”…”;

}

}

3.3.5          Löschen von Instanzen

Soll eine Instanz nicht konvertiert sondern gelöscht werden, so muss in einer der aufgerufenen Änderungsmethoden die Methode delete() aufgerufen werden. Das führt zum Abbruch der Konvertierung der aktuellen Instanz und diese wird nicht übernommen. Nach der Methode delete() muss die Änderungsmethode mit return verlassen werden. Nach delete() dürfen keine weiteren Befehle mehr stehen.

3.3.6          Datentypen

Der Datentyp ist Bestandteil der Init- und Change-Methoden. In Methodennamen wird der Datentyp wie folgt kodiert:

Datentyp Bezeichnung im

Methodennamen

Part: com.cisag.app.general.obj.DomesticAmount DomesticAmount
Part: com.cisag.app.general.obj.Duration Duration
Part: com.cisag.app.general.obj.ForeignAmount ForeignAmount
Part: com.cisag.app.general.obj.Quantity Quantity
Part: com.cisag.app.general.obj.PointInTime PointInTime
com.cisag.pgm.datatype.CisAttributeTimeStamp CisDate
com.cisag.pgm.datatype.CisAttributeDate CisDate
com.cisag.pgm.datatype.CisAttributeDateUntil CisDate
com.cisag.pgm.datatype.CisCalendar Calendar
com.cisag.pgm.datatype.CisTimeInterval TimeInterval
com.cisag.pgm.datatype.CisSymbolicInterval SymbolicInterval
Binär mit Länge 123 bin123
BLOB blob
boolean bool
byte byte
char char
Dezimalzahl mit Länge 12 und 3 Nachkommastellen dec12X3
double double
float float
GUID guid
int int
long long
short short
String mit Länge 123 str123
ValueSet vset
Zeitstempel stmp

Die obigen Datentypen werden von in den Update-Klassen als Einheit behandelt, d.h. es gibt nur jeweils eine Änderungsmethode, auch wenn in der Tabelle mehrere Spalten daraus erzeugt wurden. Alle in der Tabelle nicht aufgeführten Parts und Arrays werden nicht als Einheit behandelt, sondern jede daraus erzeugte Spalte wird getrennt in den Update-Klassen behandelt.

3.3.7          Initialisierung

Für die Datentransformation der Daten eines Business Objects auf einer Datenbank werden eine oder mehrere Instanzen der Update-Klassen erzeugt. Jede Instanz einer Update-Klasse wird nur für Business Object Instanzen auf der zugehörigen Datenbank verwendet. Wenn Business Object Instanzen auf einer anderen Datenbank transformiert werden sollen, werden neue Instanzen der Update-Klasse erzeugt.

Die Update-Klassen transformieren die Daten von der Quellversion, das ist die auf der Datenbank aktive Version, in eine Zielversion, das ist für den Entwickler, die in einer Entwicklungsaufgabe gesperrte Version. Das Schema der Quell- und Zielversion kann mit den folgenden Methoden abgefragt werden:

CisObjectSchema getFromSchema()

CisObjectSchema getToSchema()

Die Methode initialize() der Update-Klasse wird vor der Verwendung bei jeder Instanz aufgerufen. Die initialize-Methode kann in der Update-Klasse überschrieben werden, um die Instanz der Update-Klasse für die Verwendung auf einer Datenbank zu initialisieren. In dieser Methode können Sie nur lesend über den generischen Zugriff auf die Business Objects zugreifen (Siehe Abschnitt „Generischer Zugriff auf Business Objects“).

Prüfen Sie in der initialize-Methode für jede Initialisierung mit der Methode getFromSchema(), ob diese erforderlich ist. Verwenden Sie das Schema der Quellversion, um dies zu prüfen.

Hinweis:

Wenn Sie ohne Bedingung komplexe Berechnungen in der initialize-Methode durchführen, werden diese bei jeder Datenmodelländerung ausgeführt und können Laufzeit zukünftiger Datenmodelländerungen negativ beeinflussen.

Beispiel:

Für die Init-Methode der Spalte „myUnit“ wird der Vorschlagswert in der initialize-Methode berechnet. Der Vorschlagswert wird nur dann benötigt, wenn die Spalte „myUnit“ in der Quellversion nicht vorhanden ist.

byte[] myUnitDefault;

 

void initialize() {

if (getFromSchema().getColumn(“myUnit”)==null) {

myUnitDefault=…

}

}

 

byte[] init$myUnit () {

return myUnitDefault;

}

3.3.8          Zugriff auf Customizing-Daten

Für die Datentransformation wird häufig der Zugriff auf das Customizing benötigt. Mit den folgenden Methoden können Sie auf Customizing-Daten zugreifen:

boolean isAvailable(String functionName)

boolean isAvailable(String functionName, byte[] organizationGuid)

Object getConfiguredValues(String functionName,

byte[] organizationGuid)

Object getConfiguredValues(String functionName)

Beachten Sie, dass die Update-Klassen unabhängig vom Zustand des Customizings lauffähig sein müssen. Damit die Update-Klassen insbesondere auf einer „leeren“ Datenbank lauffähig sind, müssen Sie immer berücksichtigen, dass diese Methoden „null“ liefern können.

Hinweis:

Wenn eine Update-Klasse bei einem unvollständigen Customizing eine Exception wirft, dann bricht die Installation der Softwareaktualisierung mit dieser Update-Klasse in Folgesystemen unter Umständen ab und kann erst nach der Korrektur der Update-Klasse fortgesetzt werden. Das Folgesystem ist während der Korrektur der Update-Klasse in einem inkonsistenten Zustand und damit nicht verfügbar.

3.4               Konvertierung

Die Konvertierung der Daten ist ein sehr wichtiger Schritt. Wenn bei der Konvertierung Daten fehlerhaft übertragen werden, gehen im schlimmsten Fall diese Daten verloren. Wenn die ursprünglichen Daten nicht rekonstruiert werden können, so ist eine Rücksicherung der betroffenen Datenbank bzw. des System erforderlich. Wenn die fehlerhafte Konvertierung an den Kunden ausgeliefert worden ist, so ist der Schaden noch schwerwiegender. Aus diesem Grund empfiehlt es sich, die Konvertierung so gut als möglich zu testen, solange das Business Object noch nicht aktiviert worden ist.

3.4.1          Konvertierung über die Datenbank

Die Konvertierung der Daten kann innerhalb der Datenbank erfolgen, wenn aus den Update-Klassen für die Konvertierung ausschließlich konstante Initialwerte oder kompatiblen Datenmodelländerungen benötigt werden. Wenn nur eine benötigte Methode eine instanzweise Konvertierung erfordert, so muss die Konvertierung über den Application-Server erfolgen.

Hinweis:

Sie können die für einen Versionssprung benötigten Methoden mit dem Befehl wrkupdcls –printUpgrade ausgeben.

Die Konvertierung über die Datenbank kann ohne temporäre Tabellen erfolgen. Die Konvertierung erfolgt vollständig innerhalb der Datenbank, ohne dass die Instanzen des Business Objects zum Application-Server übertragen werden müssen. Diese Konvertierung benötigt meist deutlich weniger Zeit als eine Datenmodelländerung pro Instanz.

Konvertierung über die Datenbank

Die aktive Tabelle wird mit ALTER TABLE verändert.

Hinweis:

Produktivsysteme dürfen möglichst nur eine kurze Zeit für das Einspielen von Softwareaktualisierungen heruntergefahren werden. Meist enthalten Produktivsysteme auch deutlich mehr Daten als die zugehörigen Entwicklungssysteme. Je mehr Daten die Tabellen des geänderten Business Objects enthalten, desto wichtiger ist die Konvertierung über die Datenbank und desto ungünstiger ist die Konvertierung über den Application-Server mit einer temporären Tabelle.

Während der Entwicklung wird immer eine temporäre Tabelle angelegt, damit auch noch nicht aktivierte Datenmodelländerungen lokal getestet werden können.

3.4.2          Konvertierung über den Application-Server

Bei komplexen Konvertierungen müssen die Update-Klassen pro Instanz aufgerufen werden. Für die Konvertierung wird eine temporäre Tabelle zum Zwischenspeichern der konvertierten Instanzen angelegt.

Die Konvertierung erfolgt über den Application-Server, wenn mindestens eine Methode, die aus den Update-Klassen für die Datenmodelländerung aufgerufen werden muss, eine instanzweise Konvertierung erfordert.

Konvertierung über den Application-Server

Die Konvertierung über den Application-Server ist langsamer als die Konvertierung über die Datenbank, erlaubt jedoch eine spezielle Logik für die Konvertierung der einzelnen Instanzen.

Wenn Sie die Konvertierung über den Application-Server durchführen, führt das zu deutlich längeren Laufzeiten beim Einspielen der Softwareaktualisierung in das Produktivsystem.

Falls die neue Version des Business Objects einen BLOB enthält, dann erfolgt die Konvertierung immer durch den Application-Server.

Über die Property „com.cisag.sys.kernel.tools.ObjectUpdateConvertWorkerNumber“ kann der Parallelisierungsgrad der Konvertierung konfiguriert werden. Mehr Informationen dazu finden Sie im Hilfe-Dokument „ERP-Propertys“.

3.5               Views

Auch Views werden zuerst temporär erzeugt, damit der Entwickler den View vor der Aktivierung testen kann. Wenn der View auf Business-Objekte zugreift, die in der gleichen Entwicklungsaufgabe sind, wird für diesen temporären View auf die konvertierten Tabellen zugegriffen.

3.6               Generierungstools

Der normale Entwicklungszyklus eines Business Objects umfasst mehrere Schritte, die mit Hilfe von Tools, Anwendungen oder externen Anwendungen durchgeführt werden müssen.

Tool Erläuterung
crtbo Das Tool crtbo (create business object) fasst die Generierung der Tabellenbeschreibung, der Mapper-Klassen, der Update-Klassen und der temporären Tabelle zusammen.
cnvbo Mit dem Befehl cnvbo (convert business object) werden die Daten aus der aktiven in die temporäre Tabelle übernommen werden.

Für die Konvertierung werden die von crtbo erzeugten Mapper und die evtl. angepassten Update-Klassen benötigt.

actbo Wenn die Entwicklungsaufgabe, in der die Objekte bearbeitet wurden, freigegeben wurde, so müssen danach mit dem Tool actbo (activate business object) die in der Aufgabe enthaltenen Objekte aktiviert werden.

Das Tool actbo erzeugt die temporären Tabellen neu und konvertiert die Daten von der aktiven in die temporären Tabellen. Nach der Konvertierung werden die aktiven Tabellen gelöscht und die temporären Tabellen aktiviert bzw. die aktiven Tabellen mit ALTER TABLE verändert. Danach kann die Entwicklungsaufgabe aktiviert werden.

rmvbo Die Generierung der temporären Tabellen kann mit rmvbo (remove business object) unter Angabe des Objekts oder der Entwicklungsaufgabe rückgängig gemacht werden. Das Objekt wird aus der Entwicklungsaufgabe entfernt.
wrkupdcls Das Tool wrkupdcls (work update class) unterstützt den Entwickler mit zusätzlichen Informationen und Hilfestellungen:

·         -printUpgrade

Anzeige aller Methoden der Update-Klassen eines Business Objects, die bei einem Versionssprung ausgeführt werden.

·         -printHistory

Anzeige der Änderungshistorie eines Business Objects.

 

Der normale Zyklus zur Bearbeitung von Views und Businessobjekten ist somit wie folgt:

  1. Bearbeitung des Objekts in der Anwendung “Entwicklungsobjekte”.
  2. Generierung aller Objekte in der Entwicklungsaufgabe xyz mit:

crtbo –j:xyz

  1. Bearbeitung der Update-Klassen für die Konvertierung der Daten.
  2. Kompilieren der Mapper und des Updateprogramms.
  3. Neustart des Application-Servers mit dem die Daten konvertiert werden sollen.
  4. Konvertierung der Daten aus den aktiven Tabellen in die temporären Tabellen mit dem neuen Schema mit:

cnvbo –j:xyz

  1. Testen der Konvertierung, d.h. kontrollieren, ob alle Daten entsprechend in die temporären Tabellen übernommen wurden. Testen der Anwendung mit der neuen Version des Business Objects. Dies ist oft nur eingeschränkt möglich, da die temporären Tabellen standardmäßig nicht schreibbar sind. Der Test der Anwendung muss dann nach der Aktivierung erfolgen.
  2. Freigabe der Entwicklungsaufgabe xyz.
  3. Aktivierung aller temporären Tabellen in der Entwicklungsaufgabe mit:

actbo –j:xyz

  1. Aktivierung der Entwicklungsaufgabe xyz.
  2. Neustart aller Application-Server im System.

Im normalen Entwicklungsbetrieb kann es vorkommen, dass man nach die Änderungen der Metadaten eines Objekts mehrfach anpassen muss. Die Schritte 1. bis 7. können daher je nach Bedarf beliebig häufig durchlaufen werden. Die Schritte 8. bis 11. können hingegen nur sequentiell und auch nur in dieser festen Reihenfolge ausgeführt werden.

Bei den Tools crtbo und cnvbo kann explizit angegeben werden, mit welchen Objekten gearbeitet werden soll. Zu diesem Zweck gibt es die Optionen -j für Entwicklungsaufgaben und -o für Objekte. Im normalen Entwicklungszyklus ist meist die Option -j sinnvoll. Bei großen Entwicklungsaufgaben oder zum Testen eines speziellen Updateprogramms ist es jedoch sinnvoll, die Objekte ggf. einzeln zu generieren, um die Wartezeiten auf ein konkretes Ergebnis zu reduzieren.

Die Generierung der temporären Tabellen kann mit rmvbo unter Angabe des Objekts oder der Entwicklungsaufgabe rückgängig gemacht werden. Das Tool rmvbo entfernt das Objekt aus der Entwicklungsaufgabe. Alle Änderungen an dem Objekt gehen mit dem Aufruf von rmvbo ohne weitere Rückfrage verloren.

Das Aktivieren der Änderungen kann nur für die ganze Entwicklungsaufgabe mit dem Tool actbo -j:<Nummer der Entwicklungsaufgabe> vollzogen werden.

3.7               Extensions

Extensions erweitern die Tabelle auf der Datenbank um die in der Extension definierten Spalten. Datenbanken unterliegen jedoch Beschränkungen. Dies schränkt z.B. die maximale Breite einer Datenbankzeile ein. Die Spalten aus dem Business Object und der Extension addieren sich auf und überschreiten im ungünstigsten Fall die Maximalgröße. Mittlerweise wird empfohlen, sogenannte „Supplements“ zu verwenden. Dies sind Business Objects mit eigener Tabelle. Wurde zu einem Business Object ein Supplement definiert, so wird das Supplement bei Datenbankoperation mitgeladen bzw. mitgespeichert.

Business Objects und Parts können mit Extensions erweitert werden. Mit einer Extension kann ein Objekt um neue Eigenschaften erweitert werden. Eine Extension kann die Eigenschaften des Objekts nicht einschränken. Das bedeutet, dass eine Extension eine kompatible und konfliktfreie Erweiterung eines Business Objects oder Parts darstellt. Extensions bei Parts können im Unterschied zu Extensions auf Business Objects Konflikte auf den Standard Business Objects erzeugen.

3.7.1          Extensions bei Parts

Parts können mit einer Extension unter anderem um weitere Attribute erweitert werden. Die neuen Attribute des Parts müssen bei allen Business Objects angelegt werden, die dieses Part verwenden. Das Part kann von einer beliebigen Anzahl von Business Objects verwendet werden. Es ist im Allgemeinen nicht bekannt, welche Business Objects in einem nachgelagerten System ein Part verwenden.

Beispiel:

Das Part P wird mit einer Extension E in einem Branchenentwicklungssystem erweitert. Im nachgelagerten Kundenentwicklungssystem wird das Part P in einem Business Object B verwendet. Wenn die Extension E für P ausgeliefert wird, muss das Business Object B im Kundenentwicklungssystem neu generiert werden, damit dort die Attribute von E angelegt werden.

Die Attribute einer Extension eines Parts müssen in den Update-Klassen jedes Business Objects initialisiert werden, welches das erweiterte Part verwendet. Extensions bei Parts können somit die Modifikation von Update-Klassen erfordern, die nicht im Entwicklungsnamensraum des Entwicklungssystems liegen. Wenn eine neue Version der modifizierten der Update-Klassen installiert wird, entsteht ein manuell zu bearbeitender Konflikt.

Bespiel:

Das Attribut „abc“ des Standard Business Objects B hat als Datentyp das Part P. Das Part P wird mit der Extension E um das Attribut „xyz_bcd“ erweitert. Für die Spalte „abc.xyz_bcd“ wird die Init-Methode in den Update-Klassen von B generiert. Falls eine neue Standardversion von B installiert wird, muss der Konflikt auf den Update-Klassen von B manuell bearbeitet werden.

Das Attribut „cde_abc“ der Extension F zum Business Objects B hat als Datentyp das Part P. Das Part P wird mit der Extension E um das Attribut „xyz_bcd“ erweitert. Für die Spalte „cde_abc.xyz_bcd“ wird die Init-Methode in den Update-Klassen von F generiert. Falls eine neue Version von F installiert wird, muss der Konflikt auf den Update-Klassen von F manuell bearbeitet werden.

Hinweis:

Extensions bei Parts erzeugen potentiell immer manuellen Konfliktbearbeitungsaufwand und erzeugen Aufwand, falls Business Objects in nachfolgenden Systemen diese erweiterten Parts verwenden. Prüfen Sie also vor dem Anlegen einer Extension für ein Part gut, ob Sie das Problem nicht besser mit einer Business Object Extension oder einem Supplement lösen können. Extensions bei Business Objects oder ein Supplement sind immer konfliktfrei.

3.7.2          Verlängern eines String-Attributs

Ein String-Attribut eines Business Objects kann mit einer Business Object Extension verlängert werden. Die dazu notwendige ChangeDatatype-Methode wird in den zum verlängerten Attribut gehörigen Update-Klassen generiert. Das Verlängern eines Attributs kann somit Modifikation von Update-Klassen erfordern, die nicht im Entwicklungsnamensraum des Entwicklungssystems liegen. Wenn eine neue Version der modifizierten Update-Klasse installiert wird, kann ein manuell zu bearbeitender Konflikt entstehen.

3.7.3          Init-Methoden

Ein ERP-System kann als Standard-System installiert werden und danach können Modifikationen mit den Softwareaktualisierungen z.B. aus dem Kundenentwicklungssystem installiert werden. Für dieses Vorgehen ist es erforderlich, dass die Initialwerte der Attribute der Business Object Extensions aus den Attributen des Standard Business Objects berechnet werden können.

Beispiel:

Mit der Version 6.0.1 eines Business Objects wurde das Attribut xyz_abc im Partnerentwicklungssystem angelegt. Dann wurde in das Partnerentwicklungssystem die Version 7.0 des Business Objects eingespielt und damit entsteht die Version 7.0.1 im Partnerentwicklungssystem. Wenn nun ein Produktivsystem mit der Business Object Version 7.0 installiert wird und die Softwareaktualisierungen aus dem Partnerentwicklungssystem installiert werden, so muss die Init-Methode für xyz_abc für die Version 7.0.1 aufgerufen werden und ihren Initialwert aus der Übergebenen Objektinstanz mit der Version 7.0 berechnen können. Die Init-Methode muss weiterhin ebenfalls Objektinstanzen der Version 6.0 verarbeiten können.

3.7.4          Normaltransport

Business Object Extensions erfordern beim Einspielen von Softwareaktualisierungen aus dem Vorgängersystem normalerweise keine manuelle Konfliktbearbeitung. Manuelle Konfliktbearbeitung kann notwendig werden, wenn Extensions auf Parts angelegt worden sind oder aber, wenn String-Attribute verlängert wurden.

3.7.5          Parallele Wartung

Zu einem Entwicklungspräfix können mehrere Entwicklungssysteme mit unterschiedlichen Releases parallel gewartet werden. Falls ein Business Object oder eine Extension in einem älteren Release verändert wird, so muss das betroffene Business Object in das nächste Release übernommen werden. Dieser Vorgang muss bis zum neusten Release fortgesetzt werden. Die Übernahme des veränderten Business Objects geschieht durch einen Quertransport. Falls das transportierte Business Object im Zielsystem bereits verändert worden ist, wird die aktive Version des Business Objects in eine Konfliktaufgabe aufgenommen. Die Update-Klassen werden so generiert, dass die Update-Klassen sowohl den Sprung von der aktiven als auch die importiertem Version des Business Object auf die in der Konfliktaufgabe gesperrte Version des Business Objects unterstützen. Der Sprung von der aktiven Version zu der gesperrten Version kann im Entwicklungssystem getestet werden. Der Sprung von der importierten Version zu der gesperrten Version kann im Entwicklungssystem nicht getestet werden. Dieser Sprung wird erst dann ausgeführt, wenn ein System mit einem älteren Releasestand auf den Releasestand des Entwicklungssystems gehoben wird.

Kompatible Änderungen in älteren Releases sind relativ unproblematisch. Normalerweise müssen nur die Init-Methoden, die in der Update-Logic der gesperrten Version fehlen, aus der Update-Logic der importierten Version in die gesperrte Version übernommen werden.

Inkompatible Änderungen von Datentypen oder das Löschen von Spalten in älteren Releases sind problematisch, wenn andere Methoden in den Update-Klassen auf die veränderten Spalten zugreifen. Passen Sie alle Methoden, die auf das geänderte Attribut zugreifen entsprechend an. Die Änderungen an den Update-Klassen können im Entwicklungssystem nicht getestet werden. Für den Test der Änderungen müssen Sie den Releasewechsel in einem Testsystem testen.

Hinweis:

Inkompatible Änderungen in älteren Releases erzeugen bei paralleler Wartung einen erhöhten Konfliktbearbeitungsaufwand und größeren Testaufwand beim Releasewechsel.

Prüfen Sie gut, ob Sie eine inkompatible Änderung in einem älteren Release vermeiden können.

3.7.6          Apps

Business Object Extensions in einer App erzeugen wie üblich Update-Klassen. Die Methoden von Extensions aus einer App werden immer bei der Konvertierung nach den Methoden der Update-Klassen des Business Objects und der anderen Business Object Extensions aufgerufen.

3.8               Besonderheiten

Nicht alle möglichen Änderungen können mit den vorangegangenen Mechanismen ohne weitere Vorkehrungen durchgeführt werden.

3.8.1          Lokalisierbare Attribute

Wenn ein Business Object lokalisierbar Attribute enthält, so müssen Sie ggf. auch die Updateprogramme der NLS-Tabellen anpassen. Meist ändern sich die Spalten der existierenden NLS-Tabellen nicht, so dass dann keine Anpassungen der Update-Klassen erforderlich sind.

Wenn der Inhalt eines lokalisierbaren Attributs verändert werden soll, so muss beachtet werden, dass in den Update-Klassen des Business Objects nur die Hauptsprache der Datenbank verändert werden kann. Die Nebensprachen des Attributs müssen in den zugehörigen Update-Klassen der NLS-Tabellen verändert werden. In diesen Update-Klassen muss das zugehörige Business Object mit dem generischen Zugriff oder Result-Sets gelesen werden (siehe Abschnitt „Generischer Zugriff auf Business Objects“).

3.8.2          Neuanlage

Beim Hinzufügen eines NLS-Attributs oder wenn ein nicht lokalisierbares Attribut lokalisierbar gemacht wird, werden alle Übersetzungen mit dem Attribut-Wert der Hauptsprache des Objekts initialisiert. In so einem Fall wird immer ein objektweises Konvertieren des zugehörigen Haupt-Business Objects erzwungen. Eventuell in den Update-Klassen für das NLS-Business Object existierende changeDatatype Methoden werden nicht ausgeführt, da es ja noch keine Instanzen des NLS-Business Objects gibt, auf die sie angewendet werden könnten.

3.8.3          Primärschlüssel-Änderungen

Änderungen am Primärschlüssel eines Business Objects sind sehr kritisch und sollten soweit möglich vermieden werden.

3.8.4          Objektreferenzen

Bei einer Änderung an dem Primärschlüssel eines Business Objects werden alle Objektreferenzen ungültig. Damit verlieren Sie unter anderem alle Beziehungen von Workflowaktivitäten zu diesem Objekt.

Hinweis:

Für den Verlust der Objektreferenzen gibt es keine allgemeingültige Lösung.

Da die lokalisierbaren Attribute auch über Objektreferenzen das zugehörige Business Object referenzieren, haben die Übersetzungen nach der Änderung des Primärschlüssels keine Verbindung mehr zu dem Hauptobjekt. Wenn Sie dennoch den Primärschlüssel ändern müssen, so müssen Sie eine Datenaktualisierung erstellen, die die Objektreferenzen in den NLS-Tabellen ersetzt. Da die NLS-Tabelle zusätzlich die Primärschüsselattribute des Hauptobjekts enthält, kann für jede Übersetzung das Hauptobjekt geladen werden und damit die neue Objektreferenz berechnet werden.

Czy ten artykuł był pomocny?