> Inhalt: JavaScout-Fat-Client-Framework (JS-FCF) 

> Verzeichnis der Dokumente mit den Muster-Codes 

Muster-Code für ein BOS (Server-Side-Klasse eines Business-Object)

* Bitte beachten Sie die Hinweise und Bestimmungen bezüglich Urheberrecht, Haftungsausschluß und geschützte Marken oder Warenzeichen die für dieses Web-Dokument und möglicherweise auch für 'verlinkte' Dokumente gelten.

  • Der Betreiber dieser Web-Site (www.javascout.biz) ist nicht verantwortlich für den Inhalt von Web-Sites, die innerhalb dieses Web-Dokumentes oder anderer Dokumente von www.javascout.biz verlinkt sind.

  • Wenn dieses Web-Dokument oder andere Dokumente dieser Web-Site (www.javascout.biz) Rechte von Ihnen verletzen, oder sie glauben, dass Rechte Anderer (Dritter Personen) dadurch verletzt werden, informieren Sie bitte den Betreiber dieser Web-Site.
    Eine E-Mail können Sie ganz einfach durch anklicken des Symbols oder Textes im Frame rechts oben senden.

Dieses Dokument drucken.

 Letzte Bearbeitung dieses  Dokuments:
2012-04-02

Voraussetzungen für das Verständnis dieses Dokuments:

Grundkenntnisse in der Programmierung von Java (Klassen, Methoden, Schleifen).
Grundkenntnisse der SQL-Kommandos für relationale Datenbanksysteme.

Ungefährer Zeitbedarf zum Durcharbeiten dieses Dokuments:

Arbeitszeit:
Abhängig von der Komplexität der zu entwickelnden BOS-Klasse.
Ein Kopieren des Muster-Codes und 'Find/Replace' der 'Platzhalter' dauert ca. 10 Minuten.

Für das Implementieren komplexerer Abfragen hängt der Arbeitsaufwand stark von der Aufgabe und der Routine ab. Eine Schätzung des Zeitaufwandes kann in diesen Fällen nicht gegeben werden.

Dieses Dokument enthält Code-Muster für eine einfache Server-Side-Klasse eines BO (Business-Object) und Erweiterungen, die entsprechend den jeweiligen Anforderungen zusätzlich implementiert werden können.

Inhaltsverzeichnis:

Vorbemerkung 
Vorbedingung
 

Einfacher Muster-Code für ein BOS 
Muster-Code für ein BOS bei Verwendung der Datenbank-Tabelle 'Parameter'
 

Anleitung zur Adaptierung 
* Änderung des Namens der Java-Packages der Anwendung 
* Adaptieren des Kommentars 
* Änderung des Namens der Klasse und der 'Constructor'-Methoden 
* DBA-Objekt als Variable definieren 
* Methode
setDBAAttributes(...) adaptieren 
* Methode
store() adaptieren 
* Methode
store() adaptieren bei Verwendung des JSBS_Parameter_DBA 
* Methode
selectByUserKnownKey(...) adaptieren 
* Methode
selectByUserKnownKey(...) adaptieren bei Verwendung des JSBS_Parameter_DBA 
* Methoden
selectNext(...) und selectPrevious(...) adaptieren 
* Methoden
selectNext(...) und selectPrevious(...) adaptieren bei Verwendung des JSBS_Parameter_DBA 
* Methode 
deactivate() adaptieren 
* Methode 
isReferenced() adaptieren 

Zusätzlicher Code in der EJB-Klasse (bei Client/Server Anwendungen) 

Spezieller Muster-Code 
* Prüfen auf Konsistenz der Werte dieses BO
 
* Lesen von Attributswerten von anderen Datenbank-Tabellen - Methode 
mergeVariablexy 

Weitere Schritte und verwandte Dokumentation 

Vorbemerkung

Der Code für die Server-Side-Klasse eines BO ist wesentlich umfangreicher als die beiden anderen Klassen (Generelle Klasse bzw. Client-Side-Klasse) für ein BO oder die Klasse für ein DBA.
Die hohe Zahl der Anweisungen ist dadurch bedingt, dass verschiedene 'Constructor's und Methoden mit Service-Funktionen für die Verbindung zur Datenbank in jeder BOS-Klasse notwendig sind und diese nicht von einer Basisklasse geerbt werden können – obwohl der Code für jede BOS-Klasse gleich ist.
Das 'Erben' dieser Methoden von einer Basisklasse wird verhindert, weil Java nur erlaubt, von einer Basisklasse zu 'erben'.
Das ist durchaus sinnvoll weil sonst bei anderen Konstellationen Zweideutigkeiten auftreten würden – bei der Implementierung von BOS-Klassen aber ein Nachteil.

Für den Muster-Code des JavaScout Fat-Client-Framework (JS-FCF) wurde entschieden, dass die BOS-Klasse von der zugehörigen (Generellen) BO-Klasse erbt.
Die Entscheidung basiert auf Überlegungen zur Qualität und zum Arbeitsaufwand weil die wesentlichen 'Eigenschaften' des BO (Geschäfts-spezifische Variablen und eventuell Konstante Werte) nur in der Generellen BO-Klasse festgelegt werden müssen.

Die sich für jedes BOS wiederholenden Code-Teile beanspruchen zwar viel Platz im Muster-Code, können aber durch Kopieren des Muster-Codes und mit wenig Adaptionen für jede BOS-Klasse verwendet werden.
Die höhere Anzahl von Zeilen ist für die Laufzeit kein Nachteil weil der Compiler eine Optimierung durchführt.

Und wenn Sie die Erkärungen in dieser Vorbemerkung nicht ganz verstanden haben ist das auch kein Hindernis für das Codieren von BOS.
Für eine umfangreichere Erklärung bemühen Sie bitte eine Internet-Suchmaschine mit den Begriffen 'Java Mehrfachvererbung' ;-).

zum Inhaltsverzeichnis

Vorbedingung:

Einfacher Muster-Code für ein BOS

Welche Platzhalter durch Bezeichnungen des eigentlichen Projektes zu ersetzen sind finden Sie im Abschnitt
Anleitung zur Adaptierung.

package application_package.bos;
/*
 * Package für die Verbindung zur Datenbank. */

import java.sql.*;
/* Java-interne Klasse für ein Datum; benötigt für Umwandlung des Datums
 * in die Klasse aus der Bibliothek 'java.sql'. */

import java.util.Date;
/*
 * Basis-Klasse mit unterstützenden Methoden für die Verarbeitung von BO. */

import js_base.bo.*;
/* Basis-Klasse mit dem Minimalen Set an Parametern. Diese enthalten das Arbeitsdatum.
 * Das Arbeitsdatum wird für verschiedene Abfragen gebraucht. */

import js_base.structures.JSBS_MinimalParameters;
/*
 * Geerbte Generelle Klasse des BO. */

import application_package.bo.*;
/* DBA-Klasse für den Zugriff auf die DB-Tabelle. */
import application_package.dba.*;
/**
 * 
 * @author name[at]company
 * @date 20xx-xx-xx
 *
 * @description
 *  Server-Side Klasse für ein Business-Object (BO).
 *  Variablen dieses BO und Anwender-bekannte Identifikation sind in der
 *  (geerbten) Generellen Klasse für das BO dokumentiert.
 * 
 * @change-log
 * when          who                       why
 * -----------------------------------------------------------------
 * 
 */

public class application_entity_BOS extends application_entity_BO {
/*
 * VARIABLE dieser Klasse.
 * --------------------- */

/* Minimales Set von Parametern (Benutzer-Name, Arbeitsdatum,
 * Identifikation des Arbeitsplatzes); dieses Set wird vom Client-Side-BO übergeben . */

    
private JSBS_MinimalParameters structJSBS_MinimalParameters = null;
/*
 * Die folgenden Variablen dienen für die Verwaltung der Verbindung zur Datenbank.
 * --------------------- */
/* 
 * Referenz zur DB-Connection die außerhalb dieses Objektes definiert sind.
 * Dieser Wert wird als Parameter in einem passenden 'Constructor' übergeben. */

    
private Connection structDBCon = null;
/* 
 * Flag, ob dieses Objekt von einem BOC (Business Object, Client-Side-Class) oder
 * EJB (Enterprise Java Bean) konstruiert wurde.
 * Wenn das Flag den Wert 'false' hat, dann wurde dieses Objekt von einen anderen
 * BOS (Business Object, Server-Side-Class) konstruiert.
 * Dieses Flag entscheidet, ob innerhalb dieses Objektes ein 'commit' ausgeführt wird.
 * Ein 'commit' wird nur in jenem Objekt ausgeführt, das von einem BOC oder EJB konstruiert
 * wurde – nicht in einem Objekt, das von einem anderen BOS konstruiert wurde. */

    
private boolean bol_ObjectConstructedByBOC_or_EJB;
/*

 * ---------------------
 * Die folgende Variable ist das DBA-Objekt für den Zugriff auf die DB-Tabelle.
 * Dieses DBA-Objekt wird mehrfach gebraucht und deswegen global in der Klasse definiert. */

    
private application_dbtable_DBA
      
structapplication_dbtable_DBA = new application_dbtable_DBA();
/* --------------------
 * CONSTRUCTOR-METHODEN */

/* --------------------
 * Im 'Constructor' werden Parameter beim Erstellen eines Objektes dieser Klasse
 * übergeben.
 * Damit eine BOS-Klasse (BOS: Business Object, Server-Side) auch innerhalb eines
 * EJB (Enterprise Java Bean) verwendet werden kann, muss bereits eine Connection
 * zur Datenbank als Parameter an den 'Constructor' übergeben werden.
 * Für ein 'Set' ist es nicht erforderlich, einen 'Constructor' zu implementieren mit
 * dem auch die Werte eines anderen Objektes übernommen werden können. */

/* --------------------- */
/*
 * Constructor-Methode mit Minimal-Parametern und geöffneter DB-Connection als Parameter. */

    
public application_entity_BOS(
                JSBS_MinimalParameters parmMinParm,
                Connection parmDBCon)
{
/*
 * Aufruf der Unterstützungs-Methode zur Übernahme der Parameter-Werte. */

      constructionWithDBConnection(parmMinParm, parmDBCon);
/*
 * Annahme, dass dieses Objekt nicht durch ein BOC oder EJB konstruiert wurde.
 * Überlegung zu der unlogisch erscheinenden Entscheidung:
 * + Wenn dieses BOS-Objekt innerhalb eines BOC oder EJB konstruiert wird, dann ist zu
 *   erwarten, dass für die Klasse des BOC oder EJB das entsprechende Design-Pattern (Muster)
 *   verwendet wird.
 *   In diesem Muster ist als Vorgabe der entsprechende Parameter beim Aufruf des 'Constructors'
 *   enthalten und damit wird diese 'Constructor'-Methode nicht aufgerufen.
 * + Wenn dieses BOS-Objekt innerhalb eines anderen BOS konstruiert wird, ist es zeitsparend
 *   und einfacher verständlich, diese 'Constructor'-Methode aufzurufen.
 *   Mit dem folgenden Kommando wird das entsprechende Flag gesetzt und damit verhindert,
 *   dass versehentlich ein 'commit' oder 'rollback' zu früh innerhalb einer Transaktion
 *   ausgeführt wird. */

      
bol_ObjectConstructedByBOC_or_EJB = false;
    }
/*
 * Constructor-Methode mit Minimal-Parametern, geöffneter DB-Connection und
 * Flag, ob das Objekt von einem anderen BOS konstruiert wird, als Parameter. */

    
public application_entity_BOS(
                JSBS_MinimalParameters parmMinParm,
                Connection parmDBCon,
                
boolean parmObjectConstructedByBOC_or_EJB) {
/*
 * Aufruf der Unterstützungs-Methode zur Übernahme der Parameter-Werte. */

      constructionWithDBConnection(parmMinParm, parmDBCon);
/*
 * Setzen des Flags aus dem Parameter-Wert. */

      
bol_ObjectConstructedByBOC_or_EJB = parmObjectConstructedByBOC_or_EJB;
    }
/*
 * Constructor-Methode mit Minimal-Parametern, geöffneter DB-Connection und
 * einem BO der gleichen Klasse (aus dem die Werte übernommen werden) als Parameter. */

    
public application_entity_BOS(
                JSBS_MinimalParameters parmMinParm,
                Connection parmDBCon,
                
application_entity_BO parmapplication_entity_BO) {
/*
 * Aufruf der Unterstützungs-Methode zur Übernahme der Parameter-Werte. */

      constructionWithDBConnection(parmMinParm, parmDBCon);
/*
 * Aufruf der Unterstützungs-Methode zur Übernahme der Werte aus einem als Parameter
 * übergebenem BO. Diese Methode ist in der geerbten generellen Klasse implementiert. */

      copyFrom
application_entity_BO(parmapplication_entity_BO);
/*
 * Annahme, dass dieses Objekt nicht durch ein BOC oder EJB konstruiert wurde.
 * Überlegung zu der unlogisch erscheinenden Entscheidung:
 * + Wenn dieses BOS-Objekt innerhalb eines BOC oder EJB konstruiert wird, dann ist zu
 *   erwarten, dass für die Klasse des BOC oder EJB das entsprechende Design-Pattern (Muster)
 *   verwendet wird.
 *   In diesem Muster ist als Vorgabe der entsprechende Parameter beim Aufruf des 'Constructors'
 *   enthalten und damit wird diese 'Constructor'-Methode nicht aufgerufen.
 * + Wenn dieses BOS-Objekt innerhalb eines anderen BOS konstruiert wird, ist es zeitsparend
 *   und einfacher verständlich, diese 'Constructor'-Methode aufzurufen.
 *   Mit dem folgenden Kommando wird das entsprechende Flag gesetzt und damit verhindert,
 *   dass versehentlich ein 'commit' oder 'rollback' zu früh innerhalb einer Transaktion
 *   ausgeführt wird. */

      
bol_ObjectConstructedByBOC_or_EJB = false;
    }
/*
 * Constructor-Methode mit Minimal-Parametern, geöffneter DB-Connection,
 * einem BO der gleichen Klasse (aus dem die Werte übernommen werden) als Parameter
 * und Flag, ob das Objekt von einem anderen BOS konstruiert wird, als Parameter. */

    
public application_entity_BOS(
                JSBS_MinimalParameters parmMinParm,
                Connection parmDBCon,
                
application_entity_BO parmapplication_entity_BO,
                
boolean parmObjectConstructedByBOC_or_EJB) {
/*
 * Aufruf der Unterstützungs-Methode zur Übernahme der Parameter-Werte. */

      constructionWithDBConnection(parmMinParm, parmDBCon);
/*
 * Aufruf der Unterstützungs-Methode zur Übernahme der Werte aus einem als Parameter
 * übergebenem BO. Diese Methode ist in der geerbten generellen Klasse implementiert. */

      copyFrom
application_entity_BO(parmapplication_entity_BO);
/*
 * Setzen des Flags aus dem Parameter-Wert. */

      
bol_ObjectConstructedByBOC_or_EJB = parmObjectConstructedByBOC_or_EJB;
    }
/* ---------------------
 * METHODEN zur UNTERSTÜTZUNG der Übernahme der Parameter der CONSTRUCTOR-Methoden.
 * In diesen Methoden werden die Parameter, die in unterschiedlichen Constructor-Methoden
 * übernommen wurden auf die Variablen dieses Objekts übertragen.
 * --------------------- */

/* 
 * METHODE zum Übernehmen einer bereits geöffneten DB-Connection (Verbindung zur Datenbank). */

    
private void constructionWithDBConnection(
                JSBS_MinimalParameters parmMinParm,
                Connection parmDBConnection)
{
/*
 * Kopieren der Werte aus dem Minimalen Set der Parameter in die Variable dieses Objekts. */

      
structJSBS_MinimalParameters = new JSBS_MinimalParameters(parmMinParm);
/*
 * Übertragen der Referenz auf die DB-Connection (Verbindung zur Datenbank)
 * in die entsprechende Variable dieses Objekts. */

      
structDBCon = parmDBConnection;
    }
/* ---------------------
 * ELEMENTARE METHODEN für gesteuerte 'commit' und 'rollback' und 'insert' und 'update' der
 * haupt-zugeordneten DB-Tabelle.
 * --------------------- */

/* 
 * METHODE zum Ausführen eines 'commit' auf eine Datenbank.
 * Diese Methode wird in den Methoden zum Ausführen von Änderungen und Abfragen auf der
 * Datenbank zum Abschluss aufgerufen und damit werden die Änderungen auf der Datenbank gültig.
 * Bei Abfragen (ohne Änderung von Werten) wäre ein 'commit' nicht notwendig – durch Fehler beim
 * Code für das Erstellen der 'Connection' zur Datenbank kann es aber passieren, dass die 'Connection'
 * nicht mit 'autocommit' geöffnet wird und dann tritt bei verschiedenen DB-Systemen ein Fehler auf
 * wenn vor dem Beenden der 'Connection' kein 'commit' oder 'rollback' ausgeführt wurde.
 * Der Code in dieser Methode ist ein 'Sicherheitsnetz' um den Zugriff auf die DB auf jeden Fall
 * korrekt zu beenden. */

    
private void commitDBConnection() {
/* 
 * Wenn die DB-Connection nicht in dem Objekt, in dem dieses Objekt 'konstruiert' wurde, geöffnet wurde,
 * dann wird diese Methode sofort abgebrochen weil dann das 'commit' in einer 'darüber liegenden'
 * Methode ausgeführt wird. */

      if (! bol_ObjectConstructedByBOC_or_EJB) return;
/* 'commit' über die try/catch-Logik ausführen damit ein eventueller Fehler beim 'commit'
 * abgefangen werden kann. */

      try {
/* Ermitteln ob die Verbindung zur Datenbank im 'AutoCommit' Modus geöffnet wurde – dann ist kein
 * explizites 'commit' notwendig. */

        if (! structDBCon.getAutoCommit()) {
          
structDBCon.commit();
        }
      }
      catch (SQLException SQLExc) {
/* Fehler beim Ausführen des 'commit'; Fehler an die aufrufende Methode zurückliefern. */
        
StatusCode = CONST_DB_SYSTEM_ERROR;
        
StatusMsg = SQLExc.getMessage();
/* Um auf der sicheren Seite zu sein wird gleich noch ein 'rollback' ausgeführt. */
        rollbackDBConnection();
      }
    }
/* 
 * METHODE zum Ausführen eines 'rollback' auf eine Datenbank.
 * Diese Methode wird aufgerufen wenn in den Methoden zum Ausführen von Änderungen auf der
 * Datenbank ein Fehler aufgetreten ist und die bisher durchgeführten Änderungen rückgängig
 * gemacht werden müssen. */

    
private void rollbackDBConnection() {
/* 
 * Wenn die DB-Connection nicht in dem Objekt, in dem dieses Objekt 'konstruiert' wurde, geöffnet wurde,
 * dann wird diese Methode sofort abgebrochen weil dann das 'rollback' in einer 'darüber liegenden'
 * Methode ausgeführt wird. */

      if (! bol_ObjectConstructedByBOC_or_EJB) return;
/* 'rollback' über die try/catch-Logik ausführen damit ein eventueller Fehler abgefangen werden kann. */
      try {
/* Ermitteln ob die Verbindung zur Datenbank im 'AutoCommit' Modus geöffnet wurde – dann ist ein
 * 'rollback' sinnlos weil die 'commit'-Schritte durch das Datenbanksystem bestimmt werden. */

        if (! structDBCon.getAutoCommit()) {
          
structDBCon.rollback();
        }
      }
      catch (SQLException SQLExc) {
/* Fehler beim Ausführen des 'commit'; Fehler an die aufrufende Methode zurückliefern. */
        
StatusCode = CONST_DB_SYSTEM_ERROR;
        
StatusMsg = SQLExc.getMessage();
      }
    }
/* 
 * METHODE zum Übertragen der Attribute auf das haupt-zugeordnete DBA-Objekt. */

    
private void setDBAAttributes(application_dbtable_DBA parmapplication_dbtable_DBA) {
/* 
 * Aufruf der Methode der geerbten Klasse (Superklasse) um die 'Common Attributes'
 * zu kopieren. */

      super.setCommonDBAAttributes(parmapplication_dbtable_DBA);
/* 
 * Übertragen der geschäfts-spezifischen Werte dieses BO. */

      parm
application_dbtable_DBA.VariableName = this.BO_VariableName;
    }
/* 
 * METHODEN zum Einfügen eines Datensatzes in die DB-Tabelle.
 * Mit den verschiedenen Parametern wird gesteuert, welchen
 * Gültigkeitszeitraum der eingefügte Datensatz hat. */

/* 
 * METHODE für ein einfaches Einfügen eines Datensatzes in die DB-Tabelle.
 * Mit dem Parameter wird gesteuert, ob die Attribute 'ObjectID', 'CreatedAt'
 * und 'CreatedBy' mit Werten versorgt werden müssen.
 * Der Gültigkeitszeitraum beginnt mit dem aktuellen Datum und ist 'bis auf Weiteres'. */

    
private void internalInsert(boolean parmFirstInsert) {
/* 
 * Methode 'internalInsert' mit Parameter für das Gültigkeits-Anfangs-Datum
 * und das Gültigkeits-Ende-Datum aufrufen. */

      internalInsert(parmFirstInsert,
                     JSBS_BO_Services.getNewValidFrom(structJSBS_MinimalParameters),
                     JSBS_BO_Services.getGoodTillCancelled_SQLDate());
    }
/* 
 * METHODE zum Einfügen eines Datensatzes in die DB-Tabelle.
 * Dabei wird der Gültigkeitszeitraum in den Parametern übergeben.
 * Mit diesem Service kann die aufrufende Methode einfacher gehalten werden. */

    
private void internalInsert(boolean parmFirstInsert,
                                java.sql.Date parmValidFrom,
                                java.sql.Date parmValidTill) {
/* 
 * Gültigkeit des Datensatzes aus den Parametern übernehmen. */

      ValidFrom = parmValidFrom;
      ValidTill = parmValidTill;
/* 
 * Anwender dessen Eingabe das Einfügen des Datensatzes ausgelöst hat im zuständigen
 * Attribut speichern und Systemzeit (des Computers) übernehmen. */

      ChangedBy = structJSBS_MinimalParameters.strUserName;
      ChangedAt = new Timestamp(new Date().getTime());
/* 
 * Holen eines Surrogates (künstlicher Schlüssel) über die entsprechende Methode
 * und Prüfen, ob das Surrogat bereits als Wert für einen 'DataSetID' verwendet wurde.
 * Dabei werden maximal 9 Versuche durchgeführt einen 'ungebrauchten' Wert zu finden. */

      int intTrialCounter = 9;
      do {
/* Methode, die eine weit gestreute Zufallszahl liefert, aufrufen. */
        
DataSetID = JSBS_BO_Services.generateSurrogate();
/* Datenbankzugriff zum Prüfen ob dieses Surrogate bereits als Schlüssel benutzt wird. */
        
boolean locbolDataSetExists =
            
structapplication_dbtable_DBA.selectByDataSetID(structDBCon, this.DataSetID);
/* Prüfen ob der seltene Fall eingetreten ist, dass das Surrogat bereits verwendet wird. */
        
if (locbolDataSetExists) {
/* Reduzieren des Zählers der noch durchzuführenden Versuche und
 * wieder am Anfang der Schleife beginnen. */

          intTrialCounter--;
          
continue;
        }
        
else {
/* Vor dem weiterarbeiten prüfen ob nicht ein Fehler beim DB-Zugriff aufgetreten ist.
 * Ein Fehler wird durch eine nicht leere Error-Message signalisiert. */

          
if (structapplication_dbtable_DBA.ErrorMsg.length() > 0) {
/* DBA-Objekt meldet einen Fehler.
 * Status-Code setzen und Fehler-Meldung aus dem DBA-Objekt übernehmen. */

            
StatusCode = CONST_DB_SYSTEM_ERROR;
            
StatusMsg = structapplication_dbtable_DBA.ErrorMsg;
/* Verarbeitung abbrechen. */
            
return;
          }
/* DBA-Objekt mit generiertem Surrogat existiert noch nicht. Verarbeitung fortsetzen. */
          
if (parmFirstInsert) {
/* Erstes Data-Set eines neuen Daten-Objekts wird eingefügt.
 * Entsprechende Common Attributes versorgen. */

            
ObjectID = DataSetID;
            
CreatedAt = ChangedAt;
            
CreatedBy = ChangedBy;
          }
/* Methode zum Einfügen wenn bereits alle Attribute versorgt sind, aufrufen. */
          internalInsert();
/* INSERT abgeschlossen; Methode beenden. */
          
return;
        }
      }
while (intTrialCounter > 0);
/* 
 * Alle 9 generierten Surrogats-Werte sind bereits als Schlüssel verwendet.
 * Das weist auf eine volle DB-Tabelle hin – das in die Fehlermeldung schreiben. */

      StatusCode = CONST_DB_UNKNOWN_ERROR;
      StatusMsg = "No surrogate found after 9 trials; database-table seems to be full.";
    }
/* 
 * METHODE zum Einfügen eines Datensatzes in die DB-Tabelle wenn bereits alle Attribute
 * mit Werten versorgt sind. */

    
private void internalInsert() {

/* Übertragen der Werte der Variablen dieses BO auf die Variablen des DBA-Objektes. */
      setDBAAttributes(
structapplication_dbtable_DBA);
/* Aufrufen der Methode die das SQL-INSERT in die DB-Tabelle ausführt. */
      
structapplication_dbtable_DBA.insert(structDBCon);
/* 
 * Prüfen ob bei der DB-Operation ein Fehler aufgetreten ist. */

      
if (structapplication_dbtable_DBA.ErrorMsg.length() > 0) {
/* DBA-Objekt meldet einen Fehler.
 * Status-Code setzen und Fehler-Meldung aus dem DBA-Objekt übernehmen. */

        
StatusCode = CONST_DB_SYSTEM_ERROR;
        
StatusMsg = structapplication_dbtable_DBA.ErrorMsg;
      }
/* INSERT abgeschlossen; Methode beenden. */
      
return;
    }
/* 
 * METHODE zum Update eines bestehenden Datensatzes.
 * Die Verarbeitung ist sehr einfach weil die Geschäftslogik in der nach
 * 'außen' sichtbaren Methode ('store') vorhanden ist. */

    
private void internalUpdate() {
/* 
 * Übertragen der Werte der Variablen dieses BO auf die Variablen des DBA-Objektes. */

      setDBAAttributes(
structapplication_dbtable_DBA);
/* Aufrufen der Methode die das SQL-UPDATE in der DB-Tabelle ausführt. */
      
structapplication_dbtable_DBA.update(structDBCon);
/* 
 * Prüfen ob bei der DB-Operation ein Fehler aufgetreten ist. */

      
if (structapplication_dbtable_DBA.ErrorMsg.length() > 0) {
/* DBA-Objekt meldet einen Fehler.
 * Status-Code setzen und Fehler-Meldung aus dem DBA-Objekt übernehmen. */

        
StatusCode = CONST_DB_SYSTEM_ERROR;
        
StatusMsg = structapplication_dbtable_DBA.ErrorMsg;
      }
/* UPDATE abgeschlossen; Methode beendet. */
    }
/* ---------------------
 * METHODE zum Speichern eines BO wobei die Werte in den Attributen so wie sie sind
 * auf die Datenbank-Tabelle geschrieben werden.
 * Ist der Wert im Parameter 'parmDataSetIDToSelect' nicht '0' dann wird der Datensatz
 * mit dem im Parameter übergebenen Primärschlüssel verändert und als neuer Primärschlüssel
 * wird der Wert von 'DataSetID' in diesem BO verwendet.
 * Diese Methode ist dafür vorgesehen bei einer 'MobileClient' Version die Daten zwischen
 * einem mobilen Client und dem Server abgleichen zu können. */

    
public synchronized void synchronizedStore(double parmDataSetIDToSelect) {
/* Variable für den Status auf OK (fehlerfrei) setzen. */
      
this.StatusCode = CONST_OK;
      
this.StatusMsg = "";
/*
 * Prüfen, ob der Primärschlüssel (DataSetID) geändert werden soll.
 * In diesem Fall eine eigene Methode aufrufen damit diese Methode überschaubar bleibt. */

      
if ((parmDataSetIDToSelect != 0) && (this.DataSetID != parmDataSetIDToSelect)) {
        synchronizedStoreWithPrimaryKeyChange(parmDataSetIDToSelect);
        
return;
      }
/*
 * Ein eigenes BOS erstellen und damit Prüfen, ob bereits ein Datensatz mit gleichem
 * Primärschlüssel existiert.
 * Ein eigenes BOS ist notwendig weil sonst beim Lesen die Werte in diesem BOS
 * überschrieben würden. */

      application_entity_BOS existingapplication_entity_BOS =
          
new application_entity_BOS(structJSBS_MinimalParameters, structDBCon, false);
      existingapplication_entity_BOS.selectByDataSetID(this.DataSetID);
/*
 * Abhängig davon, ob bereits ein Datensatz mit gleichem Primärschlüssel existiert,
 * diesen Ändern oder einen neuen Datensatz einfügen. */

      
switch (existingapplication_entity_BOS.StatusCode) {
      
case JSBS_BO.CONST_NOT_FOUND:
/* Datensatz mit gleichem Primärschlüssel existiert noch nicht; Methode zum Einfügen aufrufen. */
        internalInsert();
        
break;
      
case JSBS_BO.CONST_OK:
/* Datensatz mit gleichem Primärschlüssel existiert; Methode zum Ändern aufrufen. */
        internalUpdate();
        
break;
      
default:
/* Unerwarteter Fehler beim Datenbank-Zugriff; kann nicht durch das Anwendungsprogramm behoben werden.
 * Status-Code und -Meldung auf dieses BO übertragen. */

        
this.StatusCode = existingapplication_entity_BOS.StatusCode;
        
this.StatusMsg = existingapplication_entity_BOS.StatusMsg;
        
return;
      }
    }
/* ---------------------
 * METHODE zum Speichern eines BO wobei die Werte in den Attributen und dabei auch
 * der Primärschlüssel (DataSetID) geändert wird.
 * Diese Methode ist dafür vorgesehen bei einer 'MobileClient' Version die Daten zwischen
 * einem mobilen Client und dem Server abgleichen zu können.

 * Dieser spezielle Code wurde deswegen in eine eigene Methode ausgegliedert weil auch

 * geprüft werden muss, ob nicht bereits ein Datensatz mit dem neuen Primärschlüssel

 * existiert und diesem Datensatz ein neuer Primärschlüssel zugeordnet werden muss.

 * Dieser sehr seltene Fall kann nur dann eintreten wenn gleichzeitig auf dem mobilen Client

 * und dem Server
der gleiche Primärschlüssel für verschiedene Objekte vergeben wurde. */
    
private synchronized void synchronizedStoreWithPrimaryKeyChange(double parmDataSetIDToSelect) {
/*
 * Ein eigenes BOS erstellen zum Prüfen (in der folgenden for-Schleife). */

      application_entity_BOS existingapplication_entity_BOS =
          
new application_entity_BOS(structJSBS_MinimalParameters, structDBCon, false);
/*
 * 'Ewige' for Schleife zum Prüfen ob der neue Primärschlüssel (this.DataSetID) noch nicht

 * bei einem Datensatz existiert bzw. Ändern des Primärschlüssels bei dem Datensatz, der

 * diesen Primärschlüssel verwendet. */

      for (;;) {
/*
 * Prüfen, ob bereits ein Datensatz mit dem neuen Primärschlüssel (DataSetID) existiert. */

        existingapplication_entity_BOS.selectByDataSetID(this.DataSetID);
/*
 * Abhängig davon, ob bereits ein Datensatz mit gleichem Primärschlüssel existiert,
 * bei diesem den Primärschlüssel andern oder die Daten aus diesem BO in den als Datensatz einfügen. */

        switch (existingapplication_entity_BOS.StatusCode) {
        case JSBS_BO.CONST_NOT_FOUND:
/* 
 * Datensatz mit neuem Primärschlüssel existiert noch nicht.
 * Das Ändern des bestehenden Datensatzes wird direkt über das DBA ausgeführt weil dort
 * die passende Methode vorhanden ist.
 * Zuerst Übertragen der Werte der Variablen dieses BO auf die Variablen des DBA-Objektes. */

          setDBAAttributes(structapplication_dbtable_DBA);
/* Aufrufen der Methode die das SQL-UPDATE in der DB-Tabelle ausführt. */
          structapplication_dbtable_DBA.update(structDBCon, parmDataSetIDToSelect);
/* 
 * Prüfen ob bei der DB-Operation ein Fehler aufgetreten ist. */

          if (structapplication_dbtable_DBA.ErrorMsg.length() > 0) {
/* DBA-Objekt meldet einen Fehler.
 * Status-Code setzen und Fehler-Meldung aus dem DBA-Objekt übernehmen. */

            StatusCode = CONST_DB_SYSTEM_ERROR;
            StatusMsg = structapplication_dbtable_DBA.ErrorMsg;
          }
/* UPDATE abgeschlossen; Methode beenden. */
     
     return;
    
    case JSBS_BO.CONST_OK:
/*
 * Seltener Fall, dass ein Datensatz mit neuem Primärschlüssel bereits existiert;
 * eigene Methode zum Ändern aufrufen. */

          existingapplication_entity_BOS.changePrimaryKey();
/* Prüfen, ob ein Fehler aufgetreten ist. */
          if (existingapplication_entity_BOS.StatusCode != JSBS_BO.CONST_OK) {
/* Unerwarteter Fehler beim Datenbank-Zugriff; kann nicht durch das Anwendungsprogramm behoben werden.
 * Status-Code und -Meldung auf dieses BO übertragen und Methode beenden. */

            this.StatusCode = existingapplication_entity_BOS.StatusCode;
            this.StatusMsg = existingapplication_entity_BOS.StatusMsg;
            return;
          }
          break;
        default:
/* Unerwarteter Fehler beim Datenbank-Zugriff; kann nicht durch das Anwendungsprogramm behoben werden.
 * Status-Code und -Meldung auf dieses BO übertragen. */

          this.StatusCode = existingapplication_entity_BOS.StatusCode;
          this.StatusMsg = existingapplication_entity_BOS.StatusMsg;
          return;
     
   }
      }
    }
/* ---------------------
 * METHODE zum Ändern des Primärschlüssels (DataSetID) bei einem bestehenden Datensatz.
 * Dieser sehr seltene Fall kann nur dann eintreten wenn gleichzeitig auf dem mobilen Client

 * und dem Server
der gleiche Primärschlüssel für verschiedene Objekte vergeben wurde
 * und auf der Datenbank des mobilen Clients der Primärschlüssel geändert werden muss. */

    
protected synchronized void changePrimaryKey() {
/*
 * Aufheben des bestehenden Primärschlüssels um später den zu ändernden Datensatz wieder
 * von der Datenbank lesen zu können. */

      double dblOriginalDataSetID = this.DataSetID;
/* 
 * Holen eines Surrogates (künstlicher Schlüssel) über die entsprechende Methode
 * und Prüfen, ob das Surrogat bereits als Wert für einen 'DataSetID' verwendet wurde.
 * Dabei werden maximal 9 Versuche durchgeführt einen 'ungebrauchten' Wert zu finden. */

      int intTrialCounter = 9;
      do {
/* Methode, die eine weit gestreute Zufallszahl liefert, aufrufen. */
        
DataSetID = JSBS_BO_Services.generateSurrogate();
/* Datenbankzugriff zum Prüfen ob dieses Surrogate bereits als Schlüssel benutzt wird. */
        
boolean locbolDataSetExists =
            
structapplication_dbtable_DBA.selectByDataSetID(structDBCon, this.DataSetID);
/* Prüfen ob der seltene Fall eingetreten ist, dass das Surrogat bereits verwendet wird. */
        
if (locbolDataSetExists) {
/* Reduzieren des Zählers der noch durchzuführenden Versuche und
 * wieder am Anfang der Schleife beginnen. */

          intTrialCounter--;
          
continue;
        }
        
else {
/* Vor dem weiterarbeiten prüfen ob nicht ein Fehler beim DB-Zugriff aufgetreten ist.
 * Ein Fehler wird durch eine nicht leere Error-Message signalisiert. */

          
if (structapplication_dbtable_DBA.ErrorMsg.length() > 0) {
/* DBA-Objekt meldet einen Fehler.
 * Status-Code setzen und Fehler-Meldung aus dem DBA-Objekt übernehmen. */

            
StatusCode = CONST_DB_SYSTEM_ERROR;
            
StatusMsg = structapplication_dbtable_DBA.ErrorMsg;
/* Verarbeitung abbrechen. */
            
return;
          }
/* DBA-Objekt mit generiertem Surrogat existiert noch nicht.
 * Für dieses BO ein UPDATE auf der Datenbank ausführen. */

          setDBAAttributes(structapplication_dbtable_DBA);
/* Aufrufen der Methode die das SQL-UPDATE in der DB-Tabelle ausführt. */
          structapplication_dbtable_DBA.update(structDBCon, dblOriginalDataSetID);
/* 
 * Prüfen ob bei der DB-Operation ein Fehler aufgetreten ist. */

          if (structapplication_dbtable_DBA.ErrorMsg.length() > 0) {
/* DBA-Objekt meldet einen Fehler.
 * Status-Code setzen und Fehler-Meldung aus dem DBA-Objekt übernehmen. */

            StatusCode = CONST_DB_SYSTEM_ERROR;
            StatusMsg = structapplication_dbtable_DBA.ErrorMsg;
          }
/* UPDATE abgeschlossen; Methode beenden. */
     
     return;
        }
      }
while (intTrialCounter > 0);
    }

/* ********************
 * METHODEN FÜR GESCHÄFTSBEZOGENE VERARBEITUNG.
 * Diese Methoden werden in der Client-Side-Klasse für das Business Object (BO)
 * aufgerufen wenn Daten gespeichert werden müssen.
 * 
 * Die Methode 'store' unterscheidet ob ein Geschäftsobjekt (BO / Business-Object)
 * erstmalig gespeichert werden muß oder die Daten eines bestehenden BO geändert wurden.
 * 
 * Die Methoden 'select....' führen eine Abfrage durch.
 * In dieser Klasse sind aber nur 'select...'-Methoden implementiert, die per Definition
 * maximal einen Datensatz auswählen.
 * Methoden die mehr als einen Datensatz finden könnten, werden in der Klasse
 * 
application_entity_Set_BOS_Set implementiert.
 * --------------------- */

/* 
 * METHODE zum Speichern der Werte in den Variablen dieses BO.
 * Oder technisch: Die Daten werden persistent gemacht.
 *
 * Die Methode unterscheidet, ob ein neues BO eingefügt werden soll oder ob
 * geschäfts-relevante Werte eines bestehenden BO verändert wurden.
 *
 * Ein BO ist durch eine eindeutige Anwender-Identifikation definiert.
 * Sehen Sie bitte bei der Methode 'selectByUserKnownKey(.....)' nach, welche
 * Variable die Anwender-Identifikation bilden.
 *
 * Ein neues BO wird dann eingefügt, wenn das 'Common Attribute' ObjectID den
 * Wert 0 enthält. */

    
public synchronized void store() {
/* Methode aufrufen in der eventuell die Daten des BO noch einmal auf Konsistenz geprüft
 * werden. */

      
if (! isConsistentData()) return;
/* Variable für den Status auf OK (fehlerfrei) setzen. */
      
this.StatusCode = CONST_OK;
      
this.StatusMsg = "";
/*
 * Entscheiden ob das BO neu erstellt wurde (ObjectID gleich 0) oder
 * eine Änderung eines Wertes einer Geschäfts-relevanten-Variable erfolgt ist. */

      
if (ObjectID == 0) {
/*
 * Speichern eines neuen Business-Object angefordert.
 * Prüfen, dass noch kein BO mit der gleichen Anwender-bekannten Identifikation existiert. */

        
boolean locbolDataSetExists =
          
structapplication_dbtable_DBA.selectByUserKnownKey(
              
structDBCon, structJSBS_MinimalParameters,
             
this.KeyVariable_1, this.KeyVariable_2);
        
if (locbolDataSetExists) {
/* BO mit der gleichen Anwender-bekannten Identifikation existiert bereits auf der DB-Tabelle.
 * Fehler an aufrufende Methode signalisieren, Rollback einleiten und Methode beenden. */

          
StatusCode = CONST_DUPLICATE_KEY;
          
StatusMsg = "";
          rollbackDBConnection();
          
return;
        }
        
else {
/* Kein entsprechender Datensatz gefunden; könnte aber auch ein Fehler beim DB-Zugriff sein. */
          
if (structapplication_dbtable_DBA.ErrorMsg.length() > 0) {
/* DBA-Objekt meldet einen Fehler.
 * Status-Code setzen und Fehler-Meldung aus dem DBA-Objekt übernehmen. */

            
StatusCode = CONST_DB_SYSTEM_ERROR;
            
StatusMsg = structapplication_dbtable_DBA.ErrorMsg;
/* Rollback einleiten und Methode beenden. */
            rollbackDBConnection();
            
return;
          }
        }
/* 
 * Wenn die Verarbeitung bis hierher gelaufen ist, existiert kein BO mit der
 * gleichen Anwender-bekannten Identifikation und die DB-Abfrage danach war fehlerfrei.
 * 
 * Neuen Datensatz für dieses BO in die DB-Tabelle einfügen.
 * Der Prameter signalisiert, dass es sich um den ersten Datensatz für ein neues BO handelt. */

        internalInsert(
true);
/* Prüfen ob bei der aufgerufenen Methode ein Fehler aufgetreten ist. */
        
if (StatusCode != CONST_OK) {
/* Status für dieses BO wurde in der Methode 'internalInsert(...)' in die passenden Variablen
 * übertragen. Rollback einleiten und Methode beenden. */

          rollbackDBConnection();
          
return;
        }
      }
      
else {
/*
 * Änderung eines Wertes einer Geschäfts-relevanten-Variable erfolgt.
 * Die Gültigkeit des aktuell gültigen Datensatzes wird auf den Tag vor
 * dem Arbeitsdatum (ein Parameter aus dem minimalen Set der Parameter) gesetzt.
 * Das ist das Zeichen, dass der Datensatz nicht länger gültig ist.
 * Dann wird ein neuer Datensatz mit dem gleichen ObjectID eingefügt,
 * dessen Gültigkeitsbeginn ('ValidFrom') das aktuelle Arbeitsdatum ist. */
/*
 * Zuerst wird der aktuell gültige Datensatz gelesen um zu prüfen, ob ein anderer
 * Anwender eine Änderung vorgenommen hat.
 * Die Änderung könnte in der Zeit passiert sein, als der jetzt zu ändernde Datensatz
 * gelesen wurde (um die Daten anzuzeigen) und jetzt, wo die geänderten Daten
 * gespeichert werden sollen.
 * 
 * Zum Lesen des Vergleichs-BOS wird ein neues BOS 'konstruiert' und dabei die bestehende
 * DB-Connection als Parameter übergeben. */

        
application_entity_BOS existingapplication_entity_BOS =
          
new application_entity_BOS(structJSBS_MinimalParameters, structDBCon, false);
/*
 * Datensatz mit dem DatasetID lesen; das bringt den Datensatz der vor einiger Zeit
 * gelesen wurde. */

        existing
application_entity_BOS.selectByDataSetID(this.DataSetID);
/* Mit der aufgerufenen Methode muß ein Datensatz gefunden werden.
 * Wenn das nicht der Fall ist, dann eine Fehlerbehandlung durchführen. */

        
if (existingapplication_entity_BOS.StatusCode != CONST_OK) {
/* Datensatz nicht gefunden oder ein Fehler beim DB-Zugriff ist aufgetreten.
 * Status-Code in dieses Objekt übernehmen und Fehlermeldung anpassen. */

          
this.StatusCode = existingapplication_entity_BOS.StatusCode;
          
this.StatusMsg = "Unexpected Error during re-read:" +
                              existing
application_entity_BOS.StatusMsg;
/* Rollback ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

          rollbackDBConnection();
          
return;
        }
/* Datensatz gefunden; so sollte es sein. */
/* Zuerst prüfen ob die Gültigkeit des Datensatzes in der Zwischenzeit beendet wurde.
 * Das weist auf eine Veränderung des BO hin. */

        
if (this.differentValidTill(
                existing
application_entity_BOS.ValidTill)){
/* Anderer Benutzer hat das BO inzwischen verändert. */
          
this.StatusCode = CONST_CHANGED_INBETWEEN;
          
this.StatusMsg = "";
/* Rollback ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

          rollbackDBConnection();
          
return;
        }
/* Noch prüfen ob überhaupt ein Wert einer geschäfts-relevanten Variable verändert wurde.
 * Wenn keine Veränderung erfolgt ist wird auch kein neuer Datensatz eingefügt. */

        
if (! this.isDifferent(existingapplication_entity_BOS)){
/* Keine Änderung eines Wertes einer geschäftsrelevanten Variable. */
          
this.StatusCode = CONST_NOTHING_TO_UPDATE;
          
this.StatusMsg = "";
/* Rollback ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

          rollbackDBConnection();
          
return;
        }

/*
 * Gültigkeit des bestehenden Datensatzes als 'beendet' markieren.
 * Das wird durch ein Datum vor dem aktuellen Arbeitsdatum indiziert. */

        existing
application_entity_BOS.ValidTill =
          JSBS_BO_Services.getNewValidTill(
structJSBS_MinimalParameters);
/* Änderung des bestehenden Datensatzes auf der DB-Tabelle durchführen. */

        existing
application_entity_BOS.internalUpdate();
/* Prüfen ob das Update fehlerfrei durchgeführt wurde.
 * Wenn das nicht der Fall ist, dann eine Fehlerbehandlung durchführen. */

        
if (existingapplication_entity_BOS.StatusCode != CONST_OK) {
/* Datensatz nicht gefunden oder ein Fehler beim DB-Zugriff ist aufgetreten.
 * Status-Code in dieses Objekt übernehmen und Fehlermeldung anpassen. */

          
this.StatusCode = existingapplication_entity_BOS.StatusCode;
          
this.StatusMsg = "Unexpected Error during update of existing record: " +
                              existing
application_entity_BOS.StatusMsg;
/* Rollback ausführen und wenn notwendig die DB-Connection schließen.
 * Anschließend Methode beenden. */

          rollbackDBConnection();
          
return;
        }

/*
 * Als letzte Datenbank-Operation einen neuen Datensatz mit den aktuellen Werten
 * in die DB-Tabelle einfügen.
 * Der Parameter ('false') teilt der aufgerufenen Methode mit, dass der
 * Datensatz eine Änderung eines bestehenden BO ist. */

        internalInsert(
false);
/* Prüfen ob das Insert fehlerfrei durchgeführt wurde.
 * Wenn das nicht der Fall ist, dann eine Fehlerbehandlung durchführen. */

        
if (this.StatusCode != CONST_OK) {
/* Status für dieses BO wurde in der Methode 'internalInsert(...)' in die passenden Variablen
 * übertragen. Rollback einleiten und Methode beenden. */

          rollbackDBConnection();
          
return;
        }
/* Alle DB-Operationen fehlerfrei; 'commit' ausführen. */
        commitDBConnection();
      }
    }
/* 
 * METHODE zum Selektieren eines Datensatzes mit dem Primär-Schlüssel der DB-Tabelle.
 * Es kann nur ein Datensatz gefunden werden – dieser ist Teil eines Business-Objektes (BO). */

    
public synchronized void selectByDataSetID(double parmDataSetID) {
/* Variable für den Status auf OK (fehlerfrei) setzen. */
      
this.StatusCode = CONST_OK;
      
this.StatusMsg = "";
/*
 * Datenbank-Zugriff über das DBA-Objekt ausführen. */

      
if (structapplication_dbtable_DBA.selectByDataSetID(structDBCon, parmDataSetID)) {
/* Datensatz existiert und wurde fehlerfrei gelesen.
 * Attributs-Werte auf die Varaiblen dieses BO übertragen. */

        getDBAAttributes(
structapplication_dbtable_DBA);
/* Commit ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

        commitDBConnection();
        
return;
      }
      
else {
/* Kein entsprechender Datensatz gefunden; könnte aber auch ein Fehler beim DB-Zugriff sein. */
        
if (structapplication_dbtable_DBA.ErrorMsg.length() <= 0) {
/* DBA-Objekt meldet keinen Fehler; d.h. ein passender Datensatz wurde nicht gefunden.
 * Status-Code setzen und Fehler-Meldung leer lassen. */

          
StatusCode = CONST_NOT_FOUND;
          
StatusMsg = "";
/* Rollback ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

          rollbackDBConnection();
          
return;
        }
        
else {
/* DBA-Objekt meldet einen Fehler;
 * Status-Code setzen und Fehler-Meldung aus dem DBA-Objekt übernehmen. */

          
StatusCode = CONST_DB_SYSTEM_ERROR;
          
StatusMsg = structapplication_dbtable_DBA.ErrorMsg;
/* Rollback ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

          rollbackDBConnection();
          
return;
        }
      }
    }
/* ----------------------
 * METHODE zum Selektieren des aktuell gültigen Datensatzes mit der
 * intern verwendeten Objekt-Identifikation.
 * 'Aktuell gültig' bedeutet, dass die Gültigkeit des Datensatzes mit dem
 * im Minimalen Set von Parametern übergebenen Arbeitsdatum übereinstimmt.
 * Es kann nur ein Datensatz gefunden werden – dieser ist Teil eines Business-Objektes (BO). */

    
public synchronized void selectByObjectID(double parmObjectID) {
/* Variable für den Status auf OK (fehlerfrei) setzen. */
      
this.StatusCode = CONST_OK;
      
this.StatusMsg = "";
/*
 * Datenbank-Zugriff über das DBA-Objekt ausführen. */

      
if (structapplication_dbtable_DBA.selectByObjectID(
              
structDBCon, structJSBS_MinimalParameters, parmObjectID)) {
/* Datensatz existiert und wurde fehlerfrei gelesen.
 * Attributs-Werte auf die Variablen dieses BO übertragen. */

        getDBAAttributes(
structapplication_dbtable_DBA);
/* Commit ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

        commitDBConnection();
        
return;
      }
      
else {
/* Kein entsprechender Datensatz gefunden; könnte aber auch ein Fehler beim DB-Zugriff sein. */
        
if (structapplication_dbtable_DBA.ErrorMsg.length() <= 0) {
/* DBA-Objekt meldet keinen Fehler; d.h. ein passender Datensatz wurde nicht gefunden.
 * Status-Code setzen und Fehler-Meldung leer lassen. */

          
StatusCode = CONST_NOT_FOUND;
          
StatusMsg = "";
/* Rollback ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

          rollbackDBConnection();
          
return;
        }
        
else {
/* DBA-Objekt meldet einen Fehler;
 * Status-Code setzen und Fehler-Meldung aus dem DBA-Objekt übernehmen. */

          
StatusCode = CONST_DB_SYSTEM_ERROR;
          
StatusMsg = structapplication_dbtable_DBA.ErrorMsg;
/* Rollback ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

          rollbackDBConnection();
          
return;
        }
      }
    }
/* ----------------------
 * METHODE zum Selektieren des aktuell gültigen Datensatzes mit der
 * Anwender-bekannten Identifikation.
 * 'Aktuell gültig' bedeutet, dass die Gültigkeit des Datensatzes mit dem
 * im Minimalen Set von Parametern übergebenen Arbeitsdatum übereinstimmt.
 * Es kann nur ein Datensatz gefunden werden – dieser ist Teil eines Business-Objektes (BO). */

    
public synchronized void selectByUserKnownKey(String parmKeyVariable_1, String parmKeyVariable_2) {
/* Variable für den Status auf OK (fehlerfrei) setzen. */
      
this.StatusCode = CONST_OK;
      
this.StatusMsg = "";
/*
 * Datenbank-Zugriff über das DBA-Objekt ausführen. */

      
if (structapplication_dbtable_DBA.selectByUserKnownKey(
              
structDBCon, structJSBS_MinimalParameters, parmKeyVariable_1, parmKeyVariable_2)) {
/* Datensatz existiert und wurde fehlerfrei gelesen.
 * Attributs-Werte auf die Variablen dieses BO übertragen. */

        getDBAAttributes(
structapplication_dbtable_DBA);
/* Commit ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

        commitDBConnection();
        
return;
      }
      
else {
/* Kein entsprechender Datensatz gefunden; könnte aber auch ein Fehler beim DB-Zugriff sein. */
        
if (structapplication_dbtable_DBA.ErrorMsg.length() <= 0) {
/* DBA-Objekt meldet keinen Fehler; d.h. ein passender Datensatz wurde nicht gefunden.
 * Status-Code setzen und Fehler-Meldung leer lassen. */

          
StatusCode = CONST_NOT_FOUND;
          
StatusMsg = "";
/* Rollback ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

          rollbackDBConnection();
          
return;
        }
        
else {
/* DBA-Objekt meldet einen Fehler;
 * Status-Code setzen und Fehler-Meldung aus dem DBA-Objekt übernehmen. */

          
StatusCode = CONST_DB_SYSTEM_ERROR;
          
StatusMsg = structapplication_dbtable_DBA.ErrorMsg;
/* Rollback ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

          rollbackDBConnection();
          
return;
        }
      }
    }
/* ----------------------
 * METHODE zum Selektieren des Datensatzes mit jener Anwender-bekannten Identifikation,
 * die in der Sortier-Reihenfolge nach den Werten, die als Parameter übergeben werden,
 * auftreten.
 * Dabei kann nur ein Datensatz gefunden werden. */

    
public synchronized void selectNext(String parmKeyVariable_1, String parmKeyVariable_2,
                                     
String parmKeyVariable_3) {
/* Variable für den Status auf OK (fehlerfrei) setzen. */
      
this.StatusCode = CONST_OK;
      
this.StatusMsg = "";
/*
 * Datenbank-Zugriff über das DBA-Objekt ausführen. */

      
if (structapplication_dbtable_DBA.selectNext(
              
structDBCon, structJSBS_MinimalParameters,
              parm
KeyVariable_1, parmKeyVariable_2, parmKeyVariable_3)) {
/* Datensatz existiert und wurde fehlerfrei gelesen.
 * Attributs-Werte auf die Variablen dieses BO übertragen. */

        getDBAAttributes(
structapplication_dbtable_DBA);
/* Commit ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

        commitDBConnection();
        
return;
      }
      
else {
/* Kein entsprechender Datensatz gefunden; könnte aber auch ein Fehler beim DB-Zugriff sein. */
        
if (structapplication_dbtable_DBA.ErrorMsg.length() <= 0) {
/* DBA-Objekt meldet keinen Fehler; d.h. ein passender Datensatz wurde nicht gefunden.
 * Status-Code setzen und Fehler-Meldung leer lassen. */

          
StatusCode = CONST_NOT_FOUND;
          
StatusMsg = "";
/* Rollback ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

          rollbackDBConnection();
          
return;
        }
        
else {
/* DBA-Objekt meldet einen Fehler;
 * Status-Code setzen und Fehler-Meldung aus dem DBA-Objekt übernehmen. */

          
StatusCode = CONST_DB_SYSTEM_ERROR;
          
StatusMsg = structapplication_dbtable_DBA.ErrorMsg;
/* Rollback ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

          rollbackDBConnection();
          
return;
        }
      }
    }
/* ---------------------
 * METHODE zum Selektieren des Datensatzes mit jener Anwender-bekannten Identifikation,
 * die in der Sortier-Reihenfolge vor den Werten, die als Parameter übergeben werden,
 * auftreten.
 * Dabei kann nur ein Datensatz gefunden werden. */

    
public synchronized void selectPrevious(String parmKeyVariable_1, String parmKeyVariable_2,
                                     
String parmKeyVariable_3) {
/* Variable für den Status auf OK (fehlerfrei) setzen. */
      
this.StatusCode = CONST_OK;
      
this.StatusMsg = "";
/*
 * Datenbank-Zugriff über das DBA-Objekt ausführen. */

      
if (structapplication_dbtable_DBA.selectPrevious(
              
structDBCon, structJSBS_MinimalParameters,
              parm
KeyVariable_1, parmKeyVariable_2, parmKeyVariable_3)) {
/* Datensatz existiert und wurde fehlerfrei gelesen.
 * Attributs-Werte auf die Variablen dieses BO übertragen. */

        getDBAAttributes(
structapplication_dbtable_DBA);
/* Commit ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

        commitDBConnection();
        
return;
      }
      
else {
/* Kein entsprechender Datensatz gefunden; könnte aber auch ein Fehler beim DB-Zugriff sein. */
        
if (structapplication_dbtable_DBA.ErrorMsg.length() <= 0) {
/* DBA-Objekt meldet keinen Fehler; d.h. ein passender Datensatz wurde nicht gefunden.
 * Status-Code setzen und Fehler-Meldung leer lassen. */

          
StatusCode = CONST_NOT_FOUND;
          
StatusMsg = "";
/* Rollback ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

          rollbackDBConnection();
          
return;
        }
        
else {
/* DBA-Objekt meldet einen Fehler;
 * Status-Code setzen und Fehler-Meldung aus dem DBA-Objekt übernehmen. */

          
StatusCode = CONST_DB_SYSTEM_ERROR;
          
StatusMsg = structapplication_dbtable_DBA.ErrorMsg;
/* Rollback ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

          rollbackDBConnection();
          
return;
        }
      }
    }
/* -----------------------------
 * METHODE zum 'Deaktivieren' dieses BO.
 * 'Deaktivieren' bedeutet, dass die Gültigkeit des aktuellen Datensatzes und eventuell
 * in Zukunft gültiger Datensätze beendet wird.
 * Dazu wird in den Datensätzen, deren 'ValidTill' (Gültig Bis Datum) gleich
oder größer
 * ist als das aktuelle Datum (das beim 'Konstruieren' dieses Objektes als Teil der
 * Struktur 'JSBS_MinimalParameters' übergeben wurde), ValidTill auf den Tag vor dem
 * aktuellen Tag gesetzt.
 * Zur Dokumentation wer (welcher Anwender) zu welcher Systemzeit das Deaktivieren
 * ausgeführt hat, wird ein neuer Datensatz eingefügt der mit dem aktuellen Datum beginnt
 * und am Tag vor dem aktuellen Datum endet. */

    
public synchronized void deactivate() {
/* Variable für den Status auf OK (fehlerfrei) setzen. */
      
this.StatusCode = CONST_OK;
      
this.StatusMsg = "";
/*
 * Prüfen, ob das BO überhaupt deaktiviert werden darf.
 * Ein eventueller (Fehler-)Status-Code wird in der Methode 'isReferenced' gesetzt. */

      
if (isReferenced()) {
/* Das BO darf nicht deaktiviert werden weil es noch von einem anderen BO referenziert wird.
 * Status-Code (warum das BO nicht deaktiviert werden darf) und Status-Message 
 * (üblicherweise die Anwender-bekannte Identifikation des referenzierenden BOs) werden
 * in der Methode 'isReferenced()' mit Werten versorgt.
 * Rollback ist zwar nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

        rollbackDBConnection();
        
return;
      }
      
else {
/* BO kann deaktiviert werden.
 * Ein DBA-Set-Objekt erstellen mit dem alle Datensätze für den ObjectID selektiert werden. */

        
application_dbtable_DBA_Set structapplication_dbtable_DBA_Set =
          
new application_dbtable_DBA_Set();
/* Datenbank-Zugriff über das DBA_Set-Objekt ausführen. */
        struct
application_dbtable_DBA_Set.selectAllByObjectID(structDBCon, this.ObjectID);
/* Prüfen ob der DB-Zugriff fehlerfrei war. */
        
if (structapplication_dbtable_DBA_Set.ErrorMsg.length() > 0) {
/* DBA-Objekt meldet einen Fehler;
 * Status-Code setzen und Fehler-Meldung aus dem DBA-Objekt übernehmen. */

          
StatusCode = CONST_DB_SYSTEM_ERROR;
       
  StatusMsg = structapplication_dbtable_DBA_Set.ErrorMsg;
/* Rollback ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

          rollbackDBConnection();
          
return;
        }
/* Kein DB-System-Fehler bei der Datenbank-Operation; Set mit den Datensätzen
 * weiter bearbeiten.
 * Dazu Hilf-Variable für die Bearbeitung des Vector definieren.
*/
        
int intDBA_Set_Size = structapplication_dbtable_DBA_Set.vecRecordSet.size();
        
int intDBA_Set_Index = 0;
/* Ein BOS definieren dessen Methoden später für das ordnungsgemäße 'Beenden' eines
 * Datensatzes verwendet werden können. */

        
application_entity_BOS structapplication_entity_BOS =
          
new application_entity_BOS(structJSBS_MinimalParameters, structDBCon);
/* Datums-Werte die für Vergleiche gebraucht werden im java.sql.Date-Format
 * definieren bzw. gleich umwandeln. */

        java.sql.Date dteWorkDate =
          
new java.sql.Date(structJSBS_MinimalParameters.calWorkDate.getTime().getTime());
        java.sql.Date dteReadValidTill;
/* In einer for-Schleife jeden Datensatz untersuchen und bei Bedarf 'beenden'. */
        
for (intDBA_Set_Index = 0; intDBA_Set_Index < intDBA_Set_Size; intDBA_Set_Index++) {
/* Indizierten Datensatz aus dem Set 'holen'. */   
          
structapplication_dbtable_DBA = (application_dbtable_DBA) 
            struct
application_dbtable_DBA_Set.vecRecordSet.elementAt(intDBA_Set_Index);
/* Letzten Tag der Gültigkeit in ein Format umwandeln das sich leichter vergleichen lässt. */
          dteReadValidTill =
structapplication_dbtable_DBA.ValidTill;
/* Nur jene Datensätze deaktivieren die nach dem aktuellen Datum enden. */
          
if (structapplication_dbtable_DBA_Set.endsAfterWorkDate(dteWorkDate, dteReadValidTill)) {
/* Werte des DBA in das vorher 'konstruierte' BOS übernehmen.
 * Grund: In der BOS-Klasse sind schon die Methoden implementiert, die die Gültigkeit eines
 * Datensatzes ordnungsgemäß beenden. */

            struct
application_entity_BOS.getDBAAttributes(structapplication_dbtable_DBA);
/* Status-Code initialisieren.
 * Diese Variable wird bei einer 'internen' Methode nicht initialisiert. */

            struct
application_entity_BOS.StatusCode = CONST_OK;
/* Ende der Gültigkeit des Datensatzes abhängig vom aktuellen Datum setzen. */
            struct
application_entity_BOS.ValidTill =
              JSBS_BO_Services.getNewValidTill(
structJSBS_MinimalParameters);
/* Methode zum Ändern der Werte aufrufen. */
            struct
application_entity_BOS.internalUpdate();
/* Prüfen ob beim 'Update' ein Fehler aufgetreten ist. */
            
if (structapplication_entity_BOS.StatusCode != CONST_OK) {
/* Fehler-Code und -Nachricht auf die Variablen dieses BO übernehmen. */
              
this.StatusCode = structapplication_entity_BOS.StatusCode;
              
this.StatusMsg = structapplication_entity_BOS.StatusMsg;
/* Rollback ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

              rollbackDBConnection();
              
return;
            }
/* Methode zum Einfügen des Datensatzes, der die Information, wer das BO deaktiviert
 * hat, enthält. */

            struct
application_entity_BOS.internalInsert(false,
                JSBS_BO_Services.getNewValidFrom(
structJSBS_MinimalParameters),
                JSBS_BO_Services.getNewValidTill(
structJSBS_MinimalParameters));
/* Prüfen ob beim 'Insert' ein Fehler aufgetreten ist. */
            
if (structapplication_entity_BOS.StatusCode != CONST_OK) {
/* Fehler-Code und -Nachricht auf die Variablen dieses BO übernehmen. */
              
this.StatusCode = structapplication_entity_BOS.StatusCode;
              
this.StatusMsg = structapplication_entity_BOS.StatusMsg;
/* Rollback ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

              rollbackDBConnection();
              
return;
            }

/* Ende des 'if' zum Bearbeiten noch gültiger Datensätze. */
          }

/* Ende der 'for'-Schleife. */
        }
/* Alle Änderungen auf der Datenbank ohne Fehler; Commit ausführen.
 * Anschließend Methode beenden. */

        commitDBConnection();
        
return;
      }
    }
/* -----------------------------
 * METHODE zum Prüfen ob auf dieses BO in einem anderen BO eine Referenz vorhanden ist.
 * Diese Methode dient dazu, zu prüfen ob das BO deaktiviert werden darf oder nicht
 * deaktiviert werden darf weil sonst in einem anderen BO eine Inkonsistenz entsteht. */

    
private boolean isReferenced() {
/*
 * Voraussetzung für diesen Muster-Code ist, dass im referenzierenden BO (implementiert in
 * der Klasse 'BOS-Set') eine Methode vorhanden ist, die alle zum aktuellen Datum und in Zukunft
 * gültigen BOs selektiert, die das hier zu löschende BO als Fremdschlüssel referenzieren. */

/*
 * Der folgende Muster-Code muss für jede referenzierende BO-Klasse implementiert (das heisst

 * kopiert und adaptiert) werden. */

/*
 * ***** FOLGENDER MUSTER-CODE MUSS GELÖSCHT WERDEN WENN NICHT AUF REFERENZEN GEPRÜFT WIRD. *****
 * Oder er kann für das Prüfen einer weiteren Referenz kopiert werden.   */

/*
 * Ein BOS-Set definieren mit dem später geprüft werden kann, ob eine Referenz auf das hier
 * zu deaktivierende BO vorhanden ist. */

        
referencing_app_entity_BOS_Set structreferencing_app_entity_BOS_Set =
          
new referencing_app_entity_BOS_Set(structJSBS_MinimalParameters, structDBCon, true);
/* Methode zum Selektieren der Liste mit den referenzierenden BOs. */
        struct
referencing_app_entity_BOS_Set.selectValidAndFutureByVariables(
                       
this.ReferencedVariable1, this.ReferencedVariable2);
/* 
 * Prüfen ob die Datenbank-Operation fehlerfrei war; dazu den Status-Code des
 * BOC-Set abfragen. */
        switch(structreferencing_app_entity_BOS_Set.StatusCode) {
          case CONST_OK:
/* Dieses BO wird referenziert; zur Sicherheit prüfen ob auch wirklich BOs
 
* im Vector vorhanden sind. */
            if(structreferencing_app_entity_BOS_Set.vecRecordSet.size() > 0) { 
/* Entsprechenden Status-Code setzen; dieser ist in der zugehörigen 'BO-Klasse'
 
* definiert. */
              this.StatusCode CONST_DEAKTIVATE_INHIBIT_REASON_Reason;
/* Zur Information des Anwenders die Anwender-bekannte Identifikation aus dem ersten
 
* BO der Liste extrahieren und in der Status-Message zurückliefern. */
              referencing_app_entity_BO structreferencing_app_entity_BO =
                (referencing_app_entity_BO)
                  structreferencing_app_entity_BOS_Set.vecRecordSet.elementAt(0);
              this.StatusMsg = structreferencing_app_entity_BO.UserKnownKeyVariable1
                       "/" + structreferencing_app_entity_BO.UserKnownKeyVariable2;
/* 'true' als Flag zurückliefern damit dieses BO nicht deaktiviert wird. */
              return true;
            }  
            break;
          case CONST_NOT_FOUND:
/* Dieses BO wird nicht referenziert;
 
* dieses 'case' ist nur vorhanden damit nicht das 'default' zum Zug kommt wenn
 
* kein Datensatz in der Liste ist. */
            break;
          default:
/* Ein anderer Fehler ist beim Selektieren aufgetreten.
 * Status-Code und Status-Message in die Variablen dieses BO übernehmen und
 * 'true' zurückliefern damit (zur Sicherheit) dieses BO nicht deaktiviert wird. */
            this.StatusCode = structreferencing_app_entity_BOS_Set.StatusCode;
            this.StatusMsg = structreferencing_app_entity_BOS_Set.StatusMsg;
            return true;
        }  
/*
 * ***** ENDE DES ZU LÖSCHENDEN ODER KOPIERENDEN MUSTER-CODE. *****  */
/* -----------
 * Wenn notwendig hier weitere Prüfungen ob dieses BO referenziert wird einfügen.
 * Dazu den Muster-Code von oben kopieren. */
/*
 * -----------
*/ 
/*
 * Wenn diese Methode nicht mit einem Algorithmus gefüllt wird oder die Abfrage auf,
 * Referenzen kein 'true' ergibt, dann wird 'false' zurückgeliefert.
 * das ist das Signal, dass dieses BO nicht von einem anderen BO referenziert wird. */

      
return false;
    }
/* ---------------------
 * METHODE zum Prüfen auf Konsistenz der Daten dieses BO.
 
 *
 
 * Diese Methode ist dazu gedacht, eine Prüfung auf Korrektheit der Werte dieses BO durchzuführen
 
 * bevor die Daten gespeichert werden.
 
 * Eine Prüfung der Konsistenz der Daten ist dann erforderlich wenn nicht sicher gestellt werden kann,
 
 * dass bei der Eingabe der Daten die Prüfungen durchgeführt werden oder wenn die Prüfungen so komplex
 
 * sind, dass sie bei der Eingabe nicht vollständig durchgeführt werden können.
  
 *

 * Wenn die Prüfregeln nicht erüllt werden kann als genereller Status-Code die Konstante 
 * CONST_INCONSISTENT_DATA (aus der Basisklasse JSBS_BO)
verwendet werden oder es können in dieser Klasse 
 * detailliertere Konstante für den Status-Code definiert werden.
 
 *
 
 * Prüf-Algorithmen, die Werte anderer Business-Objects nicht erfordern (und damit auf die Datenbank
 
 * zugreifen müssen) soll der Algorithmus dafür in der Generellen Klasse für das BO implementiert
 
 * werden. */

    
public boolean isConsistentData() {
/* 
 * Abfragen ob in der (geerbten) Generellen Klasse für das BO die Prüfregeln 'nicht bestanden'
 
 * wurden. */
      if (! super.isConsistentData())return false;
/*
 * Anschließend ist der Algorithmus. */

      
/* 
 * Wenn in dieser Methode keine Prüfungen durchgeführt werden, werden die Daten
 
 * als 'konsistent' betrachtet. */
      return true;
    }
}

zum Inhaltsverzeichnis

Muster-Code für ein BOS bei Verwendung der Datenbank-Tabelle 'Parameter'

Die Datenbank-Tabelle Parameter ist dafür vorgesehen, BO abzuspeichern für deren Klasse keine größeren Mengen erwartet werden.

Typisch dafür sind Einstellungen für das Anwendungsprogramm oder Werte für Kategorien (z.B. die Branche von Kunden).
Im JavaScout Base-System (JSBS) ist eine JSBS_Parameter_DBA – Klasse für den Low-Level Zugriff auf die DB-Tabelle 'Parameter' implementiert, die Zugriffe auf diese Tabelle ('Parameter') implementiert hat.

Die Unterschiede zum Standard-Muster-Code sind aber so gering, dass nicht der gesamte Code gelistet wird – es wird bei den betreffenden Anleitungen der jeweilige Muster-Teil, der bei Verwendung der Datenbank-Tabelle 'Parameter' passend ist, beschrieben.

zum Inhaltsverzeichnis

Anleitung zur Adaptierung

Am leichtesten funktioniert die Anpassung des Muster-Codes an die eigenen Erfordernisse durch Kopieren des Muster-Codes und Verwendung von Edit > Find/Replace... .

Wenn vorher der zu ersetzende Text markiert wurde, wird er zu findende Text von der Suchfunktion übernommen.

Für 'Platzhalter', die nur einmalig im Muster-Code vorkommen ist die 'Find'-Funktion hilfreich zum Finden der beschriebenen 'Platzhalter'.

zum Inhaltsverzeichnis

Änderung des Namens der Java-Packages der Anwendung

package application_package.bos;
. . . . .
. . . . .
/*
 * Geerbte Generelle Klasse des BO. */

import application_package.bo.*;
/* DBA-Klasse für den Zugriff auf die DB-Tabelle. */
import application_package.dba.*;
/**

Der Name dieses Packages kommt in der ersten Zeile des Muster-Codes und - wenn den Namenskonventionen gefolgt wurde – noch weitere 2 Mal in den Namen der Packages mit den Generellen Klassen der BO und den DBA-Klassen vor.

Bei Verwendung der DB-Tabelle 'Parameter' wird das DBA aus den JavaScout Basisklassen (JSBS_Parameter_DBA) verwendet:

/*
 * Geerbte Generelle Klasse des BO. */

import application_package.bo.*;
/* DBA-Klasse für den Zugriff auf die DB-Tabelle. */
import js_base.dba.*;
/**

zum Inhaltsverzeichnis

Adaptieren des Kommentars

'Kein Kommentar ist besser als ein falscher'.

Aus diesem Grund ist im Muster-Code auch keine Hintergrund-Information über Entwurfs-Entscheidungen für das BOS vorhanden.
Meiner Erfahrung nach ist es ausreichend für die Beschreibung der Variablen des BO auf die Generelle Klasse für das BO zu verweisen.
Die einzelnen Methoden der BOS-Klasse sind innerhalb des Codes kommentiert.

zum Inhaltsverzeichnis

Änderung des Namens der Klasse

 */
public class application_entity_BOS extends application_entity_BO {
/*

Dieser Name muss mit dem Namen der Klasse übereinstimmen, der beim Eröffnen der Klasse gewählt wurde.

Der Name der Klasse kommt mehrmals im gesamten Code vor.
Deswegen empfehle ich, mit 'Find/Replace' alle Platzhalter
application_entity_BO im Muster-Code durch den gewählten Klassen-Namen zu ersetzen.
application_entity_BO als Vergleichswert wird deswegen gewählt weil damit auch die Variable für die geerbte Klasse geändert wird.

zum Inhaltsverzeichnis

DBA-Objekt als Variable definieren

/*
 * ---------------------
 * Die folgende Variable ist das DBA-Objekt für den Zugriff auf die DB-Tabelle.
 * Dieses DBA-Objekt wird mehrfach gebraucht und deswegen global in der Klasse definiert. */

    
private application_dbtable_DBA
      
structapplication_dbtable_DBA = new application_dbtable_DBA();

Als Variable ist auch das DBA- (DataBase-Access) Objekt für den Zugriff auf eine Datenbank-Tabelle definiert.
Der Name der Klasse kommt mehrmals im gesamten Code vor.
Deswegen empfehle ich, mit 'Find/Replace' alle Platzhalter
application_dbtable_DBA im Muster-Code durch den gewählten Klassen-Namen zu ersetzen.

Bei BOS für komplexere Aufgaben können auch andere DBA-Klassen notwendig sein. Der Code dafür ist dann einzeln an den richtigen Stellen zu implementieren.

Bei Verwendung der DB-Tabelle 'Parameter' wird das DBA aus den JavaScout Basisklassen (JSBS_Parameter_DBA) verwendet:

/*
 * ---------------------
 * Die folgende Variable ist das DBA-Objekt für den Zugriff auf die DB-Tabelle.
 * Dieses DBA-Objekt wird mehrfach gebraucht und deswegen global in der Klasse definiert. */

    
private JSBS_Parameter_DBA
      
structJSBS_Parameter_DBA = new JSBS_Parameter_DBA();

Nachdem diese Variable mehrmals innerhalb des Codes vorkommt, ist es sinnvoll alle 'Verwendungen' mit 'Find/Replace...' zu ändern:
Find:
application_dbtable_DBA / Replace: JSBS_Parameter_DBA.

zum Inhaltsverzeichnis

Methode setDBAAttributes(...) adaptieren

/* 
 * METHODE zum Übertragen der Attribute auf das haupt-zugeordnete DBA-Objekt. */

    
private void setDBAAttributes(application_dbtable_DBA parmapplication_dbtable_DBA) {
/* 
 * Aufruf der Methode der geerbten Klasse (Superklasse) um die 'Common Attributes'
 * zu kopieren. */

      super.setCommonDBAAttributes(parmapplication_dbtable_DBA);
/* 
 * Übertragen der geschäfts-spezifischen Werte dieses BO. */

      parm
application_dbtable_DBA.VariableName = this.BO_VariableName;
    }

Der Platzhalter für den Namen des DBA-Objekts (application_dbtable_DBA) ist durch den gültigen Namen zu ersetzen.
Dies ist wahrscheinlich schon erfolgt, wenn im Abschnitt
DBA-Objekt als Variable definieren ein 'Find/replace' über den gesamten Muster-Code ausgeführt wurde.

Für jede Variable der DBA-Klasse ist zu definieren, von welcher Variable der BO-Klasse der Wert übertragen wird.
Die Variable des BO ist in der geerbten 'Generellen Klasse' des BO definiert.

Bei Verwendung der DB-Tabelle 'Parameter' – und dem zugehörigen DBA aus den JavaScout Basisklassen (JSBS_Parameter_Set_DBA) - sind folgende Richtlinien zu beachten:

zum Inhaltsverzeichnis

Methode store() adaptieren

/*
 * Speichern eines neuen Business-Object angefordert.
 * Prüfen, dass noch kein BO mit der gleichen Anwender-bekannten Identifikation existiert. */

        
boolean locbolDataSetExists =
          structapplication_dbtable_DBA.selectByUserKnownKey(
              
structDBCon, structJSBS_MinimalParameters,
             
this.KeyVariable_1, this.KeyVariable_2);
        if (locbolDataSetExists) {
/* BO mit der gleichen Anwender-bekannten Identifikation existiert bereits auf der DB-Tabelle.
 * Fehler an aufrufende Methode signalisieren, Rollback einleiten und Methode beenden. */

          
StatusCode = CONST_DUPLICATE_KEY;
          
StatusMsg = "";
          rollbackAndCloseDBConnection(bol_structDBConOpenedInThisMethod,
                                       bol_autocommit);
          
return;
        }
        
else {
/* Kein entsprechender Datensatz gefunden; könnte aber auch ein Fehler beim DB-Zugriff sein. */
          if (structapplication_dbtable_DBA.ErrorMsg.length() > 0) {
/* DBA-Objekt meldet einen Fehler.
 * Status-Code setzen und Fehler-Meldung aus dem DBA-Objekt übernehmen. */

            
StatusCode = CONST_DB_SYSTEM_ERROR;
            StatusMsg = structapplication_dbtable_DBA.ErrorMsg;
/* Rollback einleiten und Methode beenden. */
            rollbackAndCloseDBConnection(bol_structDBConOpenedInThisMethod,
                                       bol_autocommit);
            
return;
          }
        }
/* 
 * Wenn die Verarbeitung bis hierher gelaufen ist, existiert kein BO mit der
 * gleichen Anwender-bekannten Identifikation und die DB-Abfrage danach war fehlerfrei.

Der Platzhalter für den Namen des DBA-Objekts (application_dbtable_DBA) ist durch den gültigen Namen zu ersetzen.
Dies ist wahrscheinlich schon erfolgt, wenn im Abschnitt
DBA-Objekt als Variable definieren ein 'Find/replace' über den gesamten Muster-Code ausgeführt wurde.

Bei Verwendung der DB-Tabelle 'Parameter' – und dem zugehörigen DBA aus den JavaScout Basisklassen (JSBS_Parameter_DBA) – ist die Adaptierung des folgenden Codes im Abschnitt Methode store() adaptieren bei Verwendung des JSBS_Parameter_DBA beschrieben.

Bei der Abfrage nach einem bereits existierenden DBA-Objekt mit Anwender-bekannter Identifikation
          structapplication_dbtable_DBA.selectByUserKnownKey(
              
structDBCon, structJSBS_MinimalParameters,
             
this.KeyVariable_1, this.KeyVariable_2);
sind die Parameter, die die Schlüssel-Werte übergeben, entsprechend zu adaptieren.

Die folgenden Adaptierungen der BO- und BOS-Klassen wurden schon durchgeführt, wenn Sie das 'Find/Replace' wie unter Änderung des Namens der Klasse und der 'Constructor'-Methoden beschrieben ausgeführt haben.

 * Zum Lesen des Vergleichs-BOS wird ein neues BOS 'konstruiert' und dabei die bestehende
 * DB-Connection als Parameter übergeben. */

        
application_entity_BOS existingapplication_entity_BOS =
          
new application_entity_BOS(structJSBS_MinimalParameters, structDBCon);
/*
 * Datensatz mit dem DatasetID lesen; das bringt den Datensatz der vor einiger Zeit
 * gelesen wurde. */

Der obige Code-Teil ist nur ein Beispiel; die Verwendung von Objekten der BO- und BOS-Klassen kommt mehrmals vor.

zum Inhaltsverzeichnis

Methode store() adaptieren bei Verwendung des JSBS_Parameter_DBA

Bei der Abfrage nach einem bereits existierenden DBA-Objekt mit Anwender-bekannter Identifikation ist der Parameter-Name ein Teil des Schlüssels und als Parameter beim Aufruf der Methode zu übergeben.
Als weitere Parameter können bis zu 5 Werte übergeben werden. Diese Werte entsprechen den Attributen
Value01 bis Value05 der Datenbank-Tabelle.
Im folgenden Muster-Code werden 2 Variablen des BO als Schlüssel-Werte als Parameter beim Aufruf der Methode übergeben.
Die Methode akzeptiert die Übergabe von 0 bis 5 Werten als Anwender-bekannte Identifikation.

          structJSBS_Parameter_DBA.selectByUserKnownKey(
              
structDBCon, structJSBS_MinimalParameters,
              
CONST_PARAMETER_NAME,
              
this.KeyVariable_1, this.KeyVariable_2);

zum Inhaltsverzeichnis

Methode selectByUserKnownKey(...) adaptieren

/* 
 * METHODE zum Selektieren des aktuell gültigen Datensatzes mit der
 * Anwender-bekannten Identifikation.
 * 'Aktuell gültig' bedeutet, dass die Gültigkeit des Datensatzes mit dem
 * im Minimalen Set von Parametern übergebenen Arbeitsdatum übereinstimmt.
 * Es kann nur ein Datensatz gefunden werden – dieser ist Teil eines Business-Objektes (BO). */

    public synchronized void selectByUserKnownKey(String parmKeyVariable_1, String parmKeyVariable_2) {
/* Lokales Flag setzen, dass in dieser Methode keine Änderungen auf der DB-Tabelle erfolgen.
 * Damit erfolgt auch kein 'commit' durch den implementierten Code.

In der Methoden-Deklaration sind die Parameter, die die Anwender-bekannte Identifikation bilden, zu adaptieren.

/*
 * Datenbank-Zugriff über das DBA-Objekt ausführen. */

      if (structapplication_dbtable_DBA.selectByUserKnownKey(
              
structDBCon, structJSBS_MinimalParameters, parmKeyVariable_1, parmKeyVariable_2)) {
/* Datensatz existiert und wurde fehlerfrei gelesen.

Die in der Methoden-Deklaration übernommenen Parameter werden beim Aufruf der zugehörigen Methode des DBA-Objektes wieder als Parameter übergeben.

Der Platzhalter für den Namen des DBA-Objekts (application_dbtable_DBA) ist durch den gültigen Namen zu ersetzen.
Das DBA-Objekt kommt mehrmals in der Methode selectByUserKnownKey(...) vor; im obigen Code-Ausschnitt wird nur ein Auftreten gezeigt.
Das Adaptieren ist wahrscheinlich schon erfolgt, wenn im Abschnitt
DBA-Objekt als Variable definieren ein 'Find/Replace' über den gesamten Muster-Code ausgeführt wurde.

zum Inhaltsverzeichnis

Methode selectByUserKnownKey(...) adaptieren bei Verwendung des JSBS_Parameter_DBA

Bei der Abfrage nach einem bereits existierenden DBA-Objekt mit Anwender-bekannter Identifikation ist der Parameter-Name ein Teil des Schlüssels und als Parameter beim Aufruf der Methode zu übergeben.
Als weitere Parameter können bis zu 5 Werte übergeben werden. Diese Werte entsprechen den Attributen
Value01 bis Value05 der Datenbank-Tabelle.
Im folgenden Muster-Code werden 2 Variablen des BO als Schlüssel-Werte als Parameter beim Aufruf der Methode übergeben.
Die Methode akzeptiert die Übergabe von 0 bis 5 Werten als Anwender-bekannte Identifikation.

/*
 * Datenbank-Zugriff über das DBA-Objekt ausführen. */

      if (structJSBS_Parameter_DBA.selectByUserKnownKey(
              
structDBCon, structJSBS_MinimalParameters,
              
CONST_PARAMETER_NAME,
              parm
KeyVariable_1, parmKeyVariable_2)) {
/* Datensatz existiert und wurde fehlerfrei gelesen.

Die in der Methoden-Deklaration übernommenen Parameter werden beim Aufruf der zugehörigen Methode des DBA-Objektes wieder als Parameter übergeben.

Das DBA-Objekt kommt mehrmals in der Methode selectByUserKnownKey(...) vor; im obigen Code-Ausschnitt wird nur das Auftreten beim Ausführen der DBA-Methode gezeigt.
Das Adaptieren ist wahrscheinlich schon erfolgt, wenn im Abschnitt
DBA-Objekt als Variable definieren ein 'Find/Replace' über den gesamten Muster-Code ausgeführt wurde.

zum Inhaltsverzeichnis

Methode selectNext(...) und selectPrevious(...) adaptieren

Als Code-Beispiele werden jene aus der Methode selectNext(...) verwendet.
Die Änderung in der Methode
selectPrevious(...) erfolgt analog.


/* 
 * METHODE zum Selektieren des Datensatzes mit jener Anwender-bekannten Identifikation,
 * die in der Sortier-Reihenfolge nach den Werten, die als Parameter übergeben werden,
 * auftreten.
 * Dabei kann nur ein Datensatz gefunden werden. */

    
public synchronized void selectNext(String parmKeyVariable_1, String parmKeyVariable_2,
                                     
String parmKeyVariable_3) {
/* Lokales Flag setzen, dass in dieser Methode keine Änderungen auf der DB-Tabelle erfolgen.

In der Methoden-Deklaration sind die Parameter, die die Anwender-bekannte Identifikation bilden, zu adaptieren.

/*
 * Datenbank-Zugriff über das DBA-Objekt ausführen. */

      
if (structapplication_dbtable_DBA.selectNext(
              
structDBCon, structJSBS_MinimalParameters,
              parm
KeyVariable_1, parmKeyVariable_2, parmKeyVariable_3)) {
/* Datensatz existiert und wurde fehlerfrei gelesen.

Die in der Methoden-Deklaration übernommenen Parameter werden beim Aufruf der zugehörigen Methode des DBA-Objektes wieder als Parameter übergeben.

Der Platzhalter für den Namen des DBA-Objekts (application_dbtable_DBA) ist durch den gültigen Namen zu ersetzen.
Das DBA-Objekt kommt mehrmals in der Methode selectNext(...) bzw. selectPrevious(...) vor; im obigen Code-Ausschnitt wird nur ein Auftreten gezeigt.
Das Adaptieren ist wahrscheinlich schon erfolgt, wenn im Abschnitt
DBA-Objekt als Variable definieren ein 'Find/Replace' über den gesamten Muster-Code ausgeführt wurde.

zum Inhaltsverzeichnis

Methode selectNext(...) und selectPrevious(...) adaptieren bei Verwendung des JSBS_Parameter_DBA

Bei der Abfrage nach einem bereits existierenden DBA-Objekt mit Anwender-bekannter Identifikation ist der Parameter-Name ein Teil des Schlüssels und als Parameter beim Aufruf der Methode zu übergeben.
Als weitere Parameter können bis zu 5 Werte übergeben werden. Diese Werte entsprechen den Attributen
Value01 bis Value05 der Datenbank-Tabelle.
Im folgenden Muster-Code werden 3 Variablen des BO als Schlüssel-Werte als Parameter beim Aufruf der Methode übergeben.
Die Methode akzeptiert die Übergabe von 0 bis 5 Werten als Anwender-bekannte Identifikation.

/*
 * Datenbank-Zugriff über das DBA-Objekt ausführen. */

      if (structJSBS_Parameter_DBA.selectNext(
              
structDBCon, structJSBS_MinimalParameters,
              
CONST_PARAMETER_NAME,
              
parmKeyVariable_1, parmKeyVariable_2, parmKeyVariable_3 )) {
/* Datensatz existiert und wurde fehlerfrei gelesen.

Die in der Methoden-Deklaration übernommenen Parameter werden beim Aufruf der zugehörigen Methode des DBA-Objektes wieder als Parameter übergeben.

Das DBA-Objekt kommt mehrmals in der Methode selectNext(...) bzw. selectPrevious(...) vor; im obigen Code-Ausschnitt wird nur das Auftreten beim Ausführen der DBA-Methode gezeigt.
Das Adaptieren ist wahrscheinlich schon erfolgt, wenn im Abschnitt
DBA-Objekt als Variable definieren ein 'Find/Replace' über den gesamten Muster-Code ausgeführt wurde.

zum Inhaltsverzeichnis

Methode deactivate() adaptieren

/* BO kann deaktiviert werden.
 * Ein DBA-Set-Objekt erstellen mit dem alle Datensätze für den ObjectID selektiert werden. */

        
application_dbtable_DBA_Set structapplication_dbtable_DBA_Set =
          
new application_dbtable_DBA_Set;
/* Datenbank-Zugriff über das DBA_Set-Objekt ausführen. */
        struct
application_dbtable_DBA_Set.selectValidAndFutureByObjectID(structDBCon, this.ObjectID) {
/* Prüfen ob der DB-Zugriff fehlerfrei war. */
        
if (structapplication_dbtable_DBA_Set.ErrorMessage.length() > 0) {
/* DBA-Objekt meldet einen Fehler;

Zum Ermitteln aller aktuell und in Zukunft gültigen Datensätze wird die passende Methode für die DBA- (DataBase-Access-) Klasse verwendet.

Der Platzhalter für den Namen des DBA-Objekts (application_dbtable_DBA) ist durch den gültigen Namen zu ersetzen.
Das DBA-Objekt kommt mehrmals in der Methode vor; im obigen Code-Ausschnitt wird nur ein Auftreten gezeigt.
Das Adaptieren ist wahrscheinlich schon erfolgt, wenn im Abschnitt
DBA-Objekt als Variable definieren ein 'Find/Replace' über den gesamten Muster-Code ausgeführt wurde.

/* Ein BOS definieren dessen Methoden später für das ordnungsgemäße 'Beenden' eines
 * Datensatzes verwendet werden können. */

        
application_entity_BOS structapplication_entity_BOS =
          
new application_entity_BOS(structJSBS_MinimalParameters, structDBCon);
/* Datums-Werte die für Vergleiche gebraucht werden im java.sql.Date-Format

Zum Ermitteln und setzen des neuen 'Gültig-Bis'-Datums werden die passenden Methoden für die BO und BOS-Klasse verwendet.

Der Platzhalter für den Namen der BO- und BOS-Objekte (application_entity_BO) ist durch den gültigen Namen zu ersetzen.
BO- und BOS-Objekte kommen mehrmals in der Methode vor; im obigen Code-Ausschnitt wird nur ein Auftreten gezeigt.
Das Adaptieren ist wahrscheinlich schon erfolgt, wenn im Abschnitt 
Änderung des Namens der Klasse und der 'Constructor'-Methoden ein 'Find/Replace' über den gesamten Muster-Code ausgeführt wurde.

zum Inhaltsverzeichnis

Methode isReferenced() adaptieren

Voraussetzung für das Implementieren der Prüfungen in dieser Methode ist, dass eine Methode zum Selektieren der referenzierenden Business-Objects implementiert ist (Beschreibung im Dokument Muster-Code für ein BOS_Set (Liste mit Business-Objects, Server-Side-Klasse)) und eine zugehörige Konstante für den Status-Code definiert ist (Beschreibung im Dokument Muster-Code für ein BO (Generelle Klasse eines Business-Object)).
Wenn nicht auf eine Referenz geprüft werden muss, dann ist der Code innerhalb der Hinweise im Kommentar zu löschen.
Im Muster-Code ist die Prüfung auf die mögliche Referenzierung durch Business-Objects einer anderen Klasse dargestellt. 
Im 'wirklichen Leben' können wahrscheinlich Business-Objects mehr als einer anderen Klasse eine Referenz auf dieses BO enthalten.
Für jede Klasse eines möglicherweise referenzierenden BO ist der Muster-Code für die Prüfung zu kopieren und zu adaptieren.

/*
 * Ein BOS-Set definieren mit dem später geprüft werden kann, ob eine Referenz auf das hier
 * zu deaktivierende BO vorhanden ist. */

        
referencing_app_entity_BOS_Set structreferencing_app_entity_BOS_Set =
          
new referencing_app_entity_BOS_Set(structJSBS_MinimalParameters, structDBCon, true);
/* Methode zum Selektieren der Liste mit den referenzierenden BOs. */
        struct
referencing_app_entity_BOS_Set.selectByVariables(
                       
this.ReferencedVariable1, this.ReferencedVariable2);
/* 
 * Prüfen ob die Datenbank-Operation fehlerfrei war; dazu den Status-Code des
 * BOC-Set abfragen. */
        switch(structreferencing_app_entity_BOS_Set.StatusCode) {

Die Klasse der möglicherweise referenzierenden BO, die Methode zum selektieren der referenzierenden BO und die Parameter der Methode müssen angepasst werden.
Die Klasse und das Objekt kommen mehrmals in der Methode vor; im obigen Code-Ausschnitt wird das Auftreten nur zu Beginn des Muster-Codes gezeigt.

            if(structreferencing_app_entity_BOS_Set.vecRecordSet.size() > 0) { 
/* Entsprechenden Status-Code setzen; dieser ist in der zugehörigen 'BO-Klasse'
 
* definiert. */
              this.StatusCode CONST_DEAKTIVATE_INHIBIT_REASON_Reason;
/* Zur Information des Anwenders die Anwender-bekannte Identifikation aus dem ersten
 
* BO der Liste extrahieren und in der Status-Message zurückliefern. */
              referencing_app_entity_BO structreferencing_app_entity_BO =
                (referencing_app_entity_BO)
                  referencing_app_entity_BOS_Set.vecRecordSet.elementAt();
              this.StatusMsg referencing_app_entity_BO.UserKnownKeyVariable1
                       "/" + referencing_app_entity_BO.UserKnownKeyVariable2;
/* 'true' als Flag zurückliefern damit dieses BO nicht deaktiviert wird. */
              return true;
            }  

Der zugehörige Status-Code und die Anwender-bekannte Identifikation des ersten referenzierenden BO, der in der Status-Message zurück geliefert wird, sind zu adaptieren.

Wenn auf eine Referenz geprüft wird, dann wird die Anweisung für das Zurückliefern von false am Ende des Codes nicht mehr erreicht und der Compiler meldet dies als Fehler.
Zur Vermeidung des Fehlers kann die Anweisung gelöscht oder 'auskommentiert' werden.

/*
 * ***** ENDE DES ZU LÖSCHENDEN ODER KOPIERENDEN MUSTER-CODE. *****  */
/* -----------
 * Wenn notwendig hier weitere Prüfungen ob dieses BO referenziert wird einfügen. */

/*
 * -----------
*/ 
/*
 * Wenn diese Methode nicht mit einem Algorithmus gefüllt wird, wird 'false' zurückgeliefert.
 * das ist das Signal, dass dieses BO nicht von einem anderen BO referenziert wird. */

//      return false;
    }

zum Inhaltsverzeichnis

Zusätzlicher Code in der EJB-Klasse (bei Client/Server Anwendungen)

Wenn das Anwendungsprogramm als Client/Server Programm, das den EJB-Mechanismus verwendet, konzipiert ist, dann ist es notwendig, den Aufruf jeder einzelnen Methode dieser Klasse auch in der Klasse und den Interfaces für das EJB aufzunehmen.

Die Anleitung dazu finden Sie unter Muster-Codes für die Klasse eines EJB (Enterprise Java Bean) mit Datenbankzugriff > Methoden für die Datenzugriffe adaptieren - generell.

zum Inhaltsverzeichnis

Spezieller Muster-Code

In diesem Teil wird Muster-Code vorgestellt, der nicht in jeder Server-seitigen Klasse eines BO vorkommen wird und deswegen nicht in den Muster-Code der Klasse aufgenommen wurde.

zum Inhaltsverzeichnis

Prüfen auf Konsistenz der Werte dieses BO

Im Muster-Code ist die Methode public boolean isConsitentData() enthalten - aber kein Algorithmus für eventuelle Prüfungen enthalten.
Prüfregeln müssen auf die jeweilige Aufgabe des BO abgestimmt sein, ein Algorithmus-Schema würde den verschiedenartigen Aufgaben nicht gerecht und deswegen wird auf einen Beispiel-Algorithmus verzichtet.

zum Inhaltsverzeichnis

Lesen von Attributswerten von anderen Datenbank-Tabellen - Methode mergeVariablexy

Ein Vorteil der Verwendung von Business-Objects (BO) ist, dass BOs mehr Information enthalten können als ein Datensatz einer DB-Tabelle.
Ein Beispiel dafür ist, dass die Variablen eines BO aus den Werten von Attributen aus verschiedenen Datenbank-Tabellen versorgt werden können.
Das erlaubt, z.B. Werte in 'Klartext' in Variablen des BO verfügbar zu haben die auf der haupt-zugeordneten Datenbank-Tabelle nur als ObjectID zu dem referenzierten Datensatz einer anderen DB-Tabelle verfügbar sind.
Im folgenden Muster-Code wird gezeigt, wie die gewünschten Werte aus einer referenzierten Datenbank-Tabelle gelesen werden können.

/* ---------------------
 * METHODE zum 'Mischen' von Variablen-Werten aus einer weiteren Datenbank-Tabelle. */

    
public void mergeVariablexy() {
/*
 * Ein BOS konstruieren über das dann das zu 'mischende' BO selektiert wird.
 * Vorteil der Verwendung eines BOS gegenüber einem DBA ist, dass bei einem BOS
 * auch eventuell weitere referenzierte Variablen-Werte mit der Selektion 'geliefert'
 * werden.
 * Über den boolschen Parameter 'true' wird signalisiert, dass die DB-Connection
 * im konstruierten BOS nicht geschlossen werden darf. */

      
referenced_app_entity_BOS structreferenced_app_entity_BOS =
          
new referenced_app_entity_BOS(structJSBS_MinimalParameters, structDBCon, true);
/* 
 * Zu 'mischendes' BO von der Datenbank lesen. */

      struct
referenced_app_entity_BOS.selectBySelectionCriteria(
          
this.Referencing_Variable);
/* 
 * Einfaches Prüfen ob das referenzierte BO gefunden wurde. */
 
      
if (structreferenced_app_entity_BOS.StatusCode == JSBS_BO.CONST_OK) {
/* 
 * Gefunden: Referenzierte Werte auf dieses BO übertragen
*/
        
this.Referenced_Variable_1 = structreferenced_app_entity_BOS.Referenced_Variable_1;
        
this.Referenced_Variable_2 = structreferenced_app_entity_BOS.Referenced_Variable_2;
      }

      
else {
/* 
 * Referenziertes BO wurde nicht gefunden. Individuell entscheiden wie reagiert werden soll !!. */




      }
    }

Aufgerufen wird diese Methode (mergeVariablexy) in den Methoden zum Selektieren bevor die Verbindung zur Datenbank (Connection) beendet wird.

/* 
 * Über die Länge des Textes mit einer eventuellen Fehler-Nachricht prüfen ob
 * die Datenbank-Abfrage fehlerfrei beendet wurde.. */

      
if (locapplication_dbtable_DBA.ErrorMsg.length() <= 1) {
/* 
 * Datensatz existiert und wurde fehlerfrei gelesen.
 * Attributs-Werte auf die Variablen dieses BOS-Set übertragen. */

        getDBAAttributes(loc
application_dbtable_DBA_Set);
/* Methode zum Übertrage von Variablen aus einem referenzierten BO aufrufen. */
        merge
Variablexy();
/* Commit ist nicht notwendig - aber in der aufgerufenen Methode wird
 * wenn notwendig die DB-Connection geschlossen.
 * Anschließend Methode beenden. */

        commitDBConnection();
        
return;
      }
      
else {
/* DBA-Objekt meldet einen Fehler;
 * Status-Code setzen und Fehler-Meldung aus dem DBA-Objekt übernehmen. */

        
StatusCode = JSBS_BO.CONST_DB_SYSTEM_ERROR;

zum Inhaltsverzeichnis

Weitere Schritte und verwandte Dokumentation

Dokument

Inhalt

Tutorial: JavaScout ProjectAssist (Java_Fatclient_01) – Server-Side BO (Business-Object) Klasse für 'ProjectLanguage'  

Schritt desTutorials für die Entwicklung von Heavyweight-Client Anwendungen in dem die Implementierung der Server-Side Klasse für das BO vorgestellt wird.

Muster-Code für ein BOS_Set (Liste mit Business-Objects, Server-Side-Klasse)  

Muster-Code für die BOS-Klasse, mit denen eine Liste von Datensätzen selektiert werden kann.
Die Verwendung dieser Klasse ist notwendig, wenn durch die Selektionskriterien mehr als ein Datensatz ausgewählt werden kann.

zum Inhaltsverzeichnis