Runtime components : Service components : Database services : Electronic Journal : Reference
  
Reference
See also
JDBCJournalSchemaGenerator code example
JDBCJournal code example
Electronic Journal exceptions
Electronic Journal external definitions
JDBCJournalSchemaGenerator code example
The JDBCJournalSchemaGenerator is normally used by a database administration application that will create and modify the tables needed by the applications using the journal. It can, then, be considered independent from the application that is requesting the journal services. Before requesting the database connection, the application must register and load the specific JDBC driver needed to work with the database, according to the database environment, as explained in Accessing a relational database using the JDBC interface in the Database Services documentation. The application can then request a connection to the database using the following method:
JDBCJournalSchemaGenerator jsg=new JDBCJournalSchemaGenerator();
jsg.connect(aDatabaseURL, aUser, aPassword
Details about the syntax of the argument aDatabaseURL can be found in the specific JDBC Driver documentation or in JDBC URLs in the Database Services documentation.
The aUser and aPassword arguments are the userid and password to log on to the database.
The following is a sample of what this database administration application can do. The application is a runable JournalSchemaManagement class that creates the journal tables for two entities, UserA and UserB, with three generations and three table columns: BRANCHNUMBER CHAR(4), AGREEMENTNUMBER INTEGER, and DUEDATE DATE.
This sample and the following database access samples are working with a remote DB2® server listening on TCP/IP port 8888. Because the sample application will work with a remote database, the application will have to register and load the specific JDBC driver before connecting to the database. This sample shows the JDBC DB2 Net Driver, which will enable the application to work with a DBMS installed on a remote workstation.
import java.util.Enumeration;
import java.sql.*;
import com.ibm.btt.base.*;
import com.ibm.btt.services.jdbc.*;

public class JournalSchemaManagement {

public static Connection connection = null;
public static JDBCJournalSchemaGenerator jsg = null;
/**
* This method creates the journal tables using the JDBCJournalSchemaGenerator class
*/
public static void main(String args[]) {

try {

// 1) Instantiate JDBCJournalSchemaGenerator...
System.out.println(">>> Instantiating JDBCJournalGenerator...");
jsg = new JDBCJournalSchemaGenerator();

// 2) Load the JDBC DB2 driver
jsg.loadDriver("COM.ibm.db2.jdbc.net.DB2Driver");

// 3) Request a database connection
jsg.connect("jdbc:db2://myhsn:8888/myDbn", "MYUSER",
"MYPASS");

} catch (DSEException e ) {System.out.println(e.getMessage());
return;

// 3) Generate all Tables...
String myJournalSchemaName="mySchema";
Vector entities = new Vector();
entities.addElement( new String ("UserA"));
entities.addElement( new String ("UserB"));
String tableDefinition = "BRANCHNUMBER CHAR(4),
AGREEMENTNUMBER INTEGER, DUEDATE
DATE";
try {
System.out.println(">>> Generating Database Schema...");
jsg.generateSchema(entities, 3, tableDefinition, myJournalSchemaName);
System.out.println(">>> Disconnecting from the database...");
jsg.disconnect();
} catch (DSEInvalidArgumentException e) {
System.out.println(e.getMessage());
return;
catch (DSEInvalidRequestException e) {
System.out.println(e.getMessage());
} catch (DSESQLException e) {
System.out.println(e.getMessage());
return;
} catch (DSEInternalErrorException e) {
System.out.println(e.getMessage());
return;
}
}
JDBCJournal code example
Once the journal schema is created, as in the JDBCJournalSchemaGenerator code example, the applications that request the journal services to access the schema tables can be started. Before requesting the database connection, an application must take care of registering and loading the specific JDBC driver needed to work with the database, according to the database environment.
The following is a sample of an application that works with the journal service provided by the toolkit, and the definition files needed to run it. The sample is implemented for a local environment, but it can be easily adapted to a client/server environment by implementing the toolkit client operation that will start the server operation calling for the journal services.
DSEDATA.XML
< !Operation data definition that will be used by the journal service-->
<field id="branchNumber"/>
<field id="agreementNumber"/>
<kColl id="accountNumber"/>
<refData refId="branchNumber"/>
<refData refId="agreementNumber"/>
</kColl>
<kColl id="myOperationData"/>
<refData refId="accountNumber"/>
<field id="dueDate"/>
</kColl>
DSECTXT.XML
<! Contexts definition sample file >
<context id="myOperationContext" type="op"/>
<refKColl refId="myOperationData"/>
</refKColl>
</context>
DSESRVCE.XML
<! Services definition sample file >
<JDBCJournal id="myJournalName" autoCommit="true"
schema="DSESCHEM"/>
<column id="BRANCHNUMBER"
dataName="accountNumber.branchNumber"/>
<column id="AGREEMENTNUMBER"
dataName="accountNumber.agreementNumber"/>
<column id="DUEDATE" dataName="dueDate"/>
</JDBCJournal>
The column tag is used to map a specific data field in the operation context to a column in the database table, and is necessary if the data field and the column do not have the same name. When an operation to the database is run, the journal instance needs to relate the data fields that are in the operation context with the columns that are defined in the database table that the journal is working with.
The way to set this relationship is by name. By default, the journal instance expects the data fields in the operation context to have the same name as the corresponding columns in the database table. Then, if a record in the database is going to be updated with a column called BRANCHNUMBER, the journal instance will try to get the value to be inserted in the record from a data field called 'BRANCHNUMBER' in the operation context. The journal instance calls the method getValueAt('BRANCHNUMBER'). In order to modify this default behavior, the journal service allows the application to define a different relationship between data fields and the columns by using the column tag. Using the previous example, the journal instance will try to get the new value for column BRANCHNUMBER in a data field named 'accountNumber.branchNumber', by calling the method getValueAt('accountNumber.branchNumber').
The dataName tag attribute can directly hold the data field name or a key name if a KeyedObject format is being used inside the Hashtable format definition.
DSEFMTS.XML
<! Formats definition sample file >
<fmtDef id="journalFormatName"/>
<hashtable>
<fObject dataName="accountNumber.branchNumber"/>
<fObject dataName="accountNumber.agreementNumber"/>
<fObject dataName="dueDate"/>
</hashtable>
</fmtDef>
With the previous XML definitions, the data fields that will be stored in the database and managed by the journal service are the branchNumber and the agreementNumber from the accountNumber keyed collection and the dueDate. The mapping to the DB2® columns is set in the DSESRVCE.XML file. The table has been previously created by the database administration application, using the JDBCJournalSchemaGenerator.
Application flow
Context jctx;
JournalService journal;
HashtableFormat journalFormat;

//Sets the toolkit environment.

if(!InitManager.isInitialized()){
InitManager.reset("file:///c:\\btt\\btt.xml");
}
//Instantiates the context and the journal service.

jctx=ContextFactory.createContext("myOperationContext");
journal=(JournalService) Service.readObject("myJournalName");

//Initializes and opens the journal service.

journal.loadDriver("COM.ibm.db2.jdbc.net.DB2Driver");
journal.connect("jdbc:db2://hostname:8888/dbname","user","passw");
journal.openForEntity( "UserA");

//Initializes the fields to be stored in the journal.

jctx.setValueAt("accountNumber.branchNumber","1234");
jctx.setValueAt("accountNumber.agreementNumber",new Integer(102));
jctx.setValueAt("dueDate",new java.sql.Date(98,5,22));

//Adds two records (with the same contents).

journal.addRecord(jctx,"journalFormatName");
journal.addRecord(jctx,"journalFormatName");

//Updates the first record with a new date.

jctx.setValueAt("dueDate",new java.sql.Date(99,6,1));
journal.updateRecord(1, jctx, "journalFormatName");

//Retrieves the second record (the last one) and updates the
//context with the retrieved information.
//The dueDate data field value has to be again 22/06/98.

journalFormat=(HashtableFormat)FormatElement.readObject(
"journalFormatName");
journalFormat.unformat(journal.retrieveLastRecord(),jctx);
java.util.Date myDate;
myDate=(java.util.Date)jctx.getValueAt("dueDate");
System.out.println(myDate.toString());

//After any journal updating, the changes to the database must be
//explicitly committed (if autoCommit is set to false).

journal.commit();

//When the application is done with the database, the connection
//and the current journal have to be closed.

journal.disconnect();
journal.close();
Electronic Journal exceptions
The Electronic Journal service throws the following exceptions:
DSEInvalidRequestException
The current state of the object is not valid for the method being called.
Action: Check the journal state and set it to active before requesting any database operation.
DSEInternalErrorException
Internal data is inconsistent.
Action: Report the error to support through the standard reporting channels.
DSEInvalidArgumentException
One of the arguments in the called method is invalid; it is an instance of an unexpected class or it is outside the expected range.
Action: Check the value of the arguments.
DSEObjectNotFoundException
An object that was supposed to exist during the process of the method has not been found.
Action: Check that your environment is set up correctly.
DSESQLException
An exception has been returned when accessing the database.
Action: Refer to the SQL documentation to take the appropriate action for the specific error number and message.
DSEException
An exception has been returned when requesting or releasing a connection from a pool of connections or when trying to share a connection.
Action: Verify that the connection pooling is available. Check the maximum number of connections defined and the connection timeout value, and possibly specify new values to avoid this exception in the future.
Electronic Journal external definitions
The Electronic Journal service has the following data externalized in the services definition file:
JDBCJournal tag
id
Name of the JDBCJournal attribute.
autoCommit
Specifies whether an automatic commit is made after each journal update:
true (default)
false
schema
Schema name. If the schema is created in the DBMS, the schema name must match the DBMS specifications (for instance, in DB2, the name must be 8 characters or fewer and uppercase).
JDBCDriver
Name of the JDBC Driver that the service will use to request the connection to the database and to execute the SQL statements.
poolName
The connection manager pool containing the connection type you want. Consult the WebSphere administrator for the pool name.
dataSourceName
The DataSource object name to be used by all requests to get a connection. This should be specified when working with the connection pooling provided by WebSphere Application Server or with any other JDBC implementation of the connection pooling. This name requires a context part and a logical name part, since it will be used to do a lookup in the naming context. A typical string might look something like "jdbc/sample," where the context is "jdbc" and the logical name is "sample." This information can be supplied by the WebSphere administrator, and it identifies the DataSource object placed in the naming service.
sharedConnection
The alias of the connection that the service wants to share with other JDBC service instances.
createSchema
A boolean value. If set to true (the default value), the service understands there is a schema in the database that keeps the journal tables. If you set this attribute to false, the service understands there is no schema created in the database for keeping the journal tables. You must set this attribute to false if the DBMS being used does not support schemas (such as DB2 UDB for OS/390).
statementPoolSize
Defines the dimension of the Statements pool. The default value is 32. Increase the value of the attribute to improve system performance or reduce the value to prevent exhausting system resources.
singleTable
Determines whether the JDBCJournal instance being instantiated and initialized uses the same table as other JDBCJournal instances. The attribute's value can be true or false (default). Set this value to true if the application uses a generic pool when requesting a Journal service instance.
column tag
id
Journal table column name used for mapping.
dataName
Operation context DataField name (or the key that keeps the data field value) used for mapping.
Go up to
Electronic Journal