IBM WebSphere Developer Technical Journal: Enabling a service-oriented architecture with SDO and the JDBC Data Access Service

This article provides an executive overview of the Data Access Services (DAS) that ship with IBM® Rational® Application Developer V6, and explains the role that these access services play in a service-oriented architecture (SOA) that uses Service Data Objects (SDO).

Share:

Robert Peterson (rrpeters@us.ibm.com), WebSphere Enablement, Austin, TX, EMC

Author photoRobert R. Peterson is part of the enablement team under IBM Software Services for WebSphere. He works to ensure that the WebSphere portfolio of products brings IBM's clients the greatest value possible. Robert is an accomplished inventor and co-author of WebSphere Application Server V6: Performance and Scalability. He is an alumni of IBM's prestigious Extreme Blue Program and holds a M.S. in Computer Engineering from the University of Florida.



26 October 2005

From the IBM WebSphere Developer Technical Journal.

Introduction

The JDBC Data Access Services included with IBM Rational Application Developer for WebSphere® Software V6 provide standardized access to the persistence layer of a service-oriented architecture. Data Access Services (DAS) are closely related to Service Data Objects (SDO), so to understand what a DAS is, we first need to look at a SDO.

Following the high-level sections in this article, we will present an end-to-end sample application that uses the JDBC DAS appropriate for a developer or architect. The example persists changes to an SDO data object graph using XML object-relational mapping information. (See Resources for more information on SDOs.)

What is a SDO?

Service Data Objects (SDO) is an emerging standard for representing data in enterprise applications. An SDO is a container for information designed to promote open standards and interoperability. An SDO provides a way to represent information throughout an enterprise application, including the presentation layer, business logic layer, persistence layer, and communication between such layers, as shown in Figure 1.

Figure 1. SDO overview
Figure 1. SDO overview

Key features of Service Data Objects are:

  • SDOs can have nested objects. This is known as an object graph, which is a very flexible way to represent data. For example, the SDO in Figure 2 represents a customer that has many orders for various products:

    Figure 2. SDO data graph
    Figure 2. SDO data graph
  • SDOs support XPath for access to the data they encapsulate. XML Path Language (XPath) is an open standard, founded by the World Wide Web Consortium (W3C), for data access from an XML document. For example, a specific product could be accessed with: CustomerOrder/Product[name='MP3Player'], where CustomerOrder is the name of the relationship defined between Customer and Order.

  • SDOs can exist as either an XML artifact or Java™ object. This transparent support for XML enables SDOs to be transported via Web services (or any XML transport such as REST or XML-RPC) by simply passing the XML SDO starting with the <datagraph> tag. Furthermore, The <datagraph> tag is only necessary in SDO v1 when using the change summary. In all other cases, any tags can be used.

  • SDOs have a change summary. The SDO change summary, which serves as a history of all activity, enables applications to distinguish old data from new data. For example, consider the scenario where a customer decides to make a new order. The enterprise system that takes the new order is composed of the high-level components shown in Figure 3. Notice that the SDO containing the new order is passed from the portal server to a backend service. Without the change summary, the backend service would have to put all the data inside the SDO into the database. However, since it has access to the SDO change summary, it only has to put the new data into the database, increasing the efficiency of the backend service. Additionally, the change summary may be used by the portal server to transport a smaller SDO with only the changes in the first place.

    Figure 3. Change summary
    Figure 3. Change summary
  • SDO is an open standard. The SDO 1.0 and 2.0 specifications were jointly released by BEA® and IBM (see Resources). Any organization is free to use and implement these standards.

What is a DAS?

A Data Access Service persists an SDO according to the SDO 1.0 standard. A DAS can be implemented for any persistence mechanism. For example, Rational Application Developer V6 includes a JDBC DAS and an EJB entity bean DAS, enabling an SDO to be persisted to various backend systems in a standard way, promoting interoperability and standards within enterprise applications.

Figure 4. DAS overview
Figure 4. DAS overview

DAS is an emerging specification that is still being standardized. DAS is to complement the SDO 2.0 specification and is in-progress (DAS was considered out of scope for the SDO 2.0 specification).


Data Access Services in a service-oriented architecture

SDO Data Access Services are ideally suited to be exposed as SOA services. They provide a standard for constructing backend services which can be shared among SOA services. For example, consider an enterprise system that must communicate with two different businesses. The business services use completely different technology to persist information. If the messages passed to those services are SDOs and the services both utilize a DAS, the enterprise application can treat them as if they were the same organization, as in Figure 5.

Figure 5. SDO Data Access Services in an SOA
Figure 5. SDO Data Access Services in an SOA

DAS can also increase maintainability for an SOA. A common pitfall with implementing an SOA is making the assumption that exposing a service is always advantageous. When a service is exposed, it is very difficult to change -- especially for services that expose some functionality to customers or to the public. For example, imagine that a bank has a service it has exposed for years, and now has to change that service due to government regulation -- messages must be encrypted over the wire, as in Figure 6.

Figure 6. DAS and maintainability in an SOA
Figure 6. DAS and maintainability in an SOA

If hundreds of partners access the service, then the bank easily change the service because its partners will no longer be able to do business with them. It is likely that the bank's best option is to build another service that is 99% redundant and try to motivate its partners to switch to the new service. This is a considerable use of resources with little justifiable business value.

SDO coupled with a DAS can alleviate this type of problem because an SDO is a very dynamic message. If the Bank was using SDO it could simply tell its partners to encrypt the additional information and the exposed service would not change -- only the message handed to that service would. In the event that a partner still sends the old SDO XML format, the bank's application will be able to readily determine the situation and handle it as it did before by inspecting the SDO's contents (and possibly contact the business partner that is not compliant).


The business case for using an SDO Data Access Service

What is the business value of using SDO coupled with a DAS over an existing persistence technology besides the benefits of an SOA? Consider the following characteristics from a management perspective:

  • SDO is an open standard. Vendor lock-in can be avoided as SDO is a public open standard. At the time of this article's publication BEA, IBM, Versant, Versata, and XCalia had all announced SDO implementations. Data access for SDO is planned to be standardized as well.

  • SDO and DAS can reduce the amount of code a business has to maintain. Data Access Services provide a standard way to persist information encapsulated in an SDO regardless of the backend system, whether it is a relational database accessed with JDBC, an LDAP server accessed by entity beans, or some other backend system that has a DAS implementation. In effect, custom code written to utilize heterogeneous backend systems is consolidated in a standard way with data access services. Less code to maintain often reduces time to market and risk by minimizing potential defects.

  • SDOs coupled with DAS are persistence technology agnostic. DAS lets applications go beyond being database or operating system independent. They allow for an application to be independent of an entire persistence technology. By using multiple data access services, an application can support the underlying persistence mechanism for those mediators without changing business logic or presentation logic. For organizations with a complex IT environment, this can reduce costs, consolidate assets, and mitigate the risk of costly technology changes in the future.

  • There are some trade-offs to using SDO and DAS. These are emerging technologies which are in early release stages. Many data access services may not support the most advanced features of other persistence technologies (unless the very technology that the DAS is built for supports such features). For example, IBM's JDBC Data Access Service does not yet support distributed cache for clustered environments of SDO graphs. Another trade-off is that harnessing the potential of using SDO and DAS may require knowledge of many recent technologies including Web services, XPath, and the SDO specifications. Training may be required for a development organization.


Using the JDBC Data Access Service, step-by-step

The balance of this article will present the implementation of a sample application. Functionally, the CloseOrderApplication closes an order for a customer with the JDBC DAS that is included with Rational Application Developer V6. The application retrieves an SDO object graph from the database, updates it, and persists the changes. The metadata to map the database schema to an SDO object graph is written in XML.

The JDBC DAS programming model

The diagram in Figure 7 illustrates the programming model that should prove useful while developing an application with the JDBC Data Access Service.

Figure 7. JDBC DAS programming model
Figure 7. JDBC DAS programming model

About the sample application
This example is more than code to play with, as it implements JavaEE best practices and realistic error handling. If you are just in need of the code to utilize the JDBC Data Access Service, which is no more than a few lines, Listings 1 and 6 will prove to be the most relevant. The database setup, JavaEE datasource definition, JNDI lookups of XML metadata, and exception handling are part of JavaEE development, not the SDO JDBC DAS.

In this model, the JDBC DAS wraps a JDBC Connection with a ConnectionWrapper to connect to the data store. A Metadata instance is created with a MetadataFactory. The metadata is then defined with constructs such as Tables, Columns, and Relationships. The equivalent of database queries are defined in the metadata as Filters. However, in this example, the metadata, tables, columns, relationships, and filters are defined in the metadata and created transparently when needed with an XML mapping document. (See Resources for a reference on how to use the metadata API at run time as illustrated above.) Once defined, the metadata is used in conjunction with the ConnectionWrapper to create a JDBCMediator. The mediator can both fetch and persist SDO DataObject graphs.

We will implement this sample application by performing the following tasks:

  1. Create a JaveEE project
  2. Setup the database
  3. Define XML metadata
  4. Create method
  5. Create a JDBC connection wrapper
  6. Create a JDBC mediator
  7. Retrieve SDO DataObject graph from database
  8. Persist the SDO graph
  9. Close the connection
  10. Review application exceptions
  11. Test application with a servlet

Sample application prerequisites

This example assumes a JavaEE environment for the SDO DAS. However, an application server is not required. The IBM JDBC DAS can be used in any application that supports Java SE 1.3 or higher.

1. Create a JavaEE project

In the J2EE perspective of Rational Application Developer:

  1. Select File => New => Enterprise Application Project. Name it CloseOrder and select Finish.

  2. Right click CloseOrder, select New => Dynamic Web Project, and name it CloseOrderWeb, then Finish.

2. Setup the database

The database schema for the sample application is shown in Figure 8. It consists of a customer entity with a foreign key to an order entity:

Figure 8. Database schema
Figure 8. Database schema

Notice that the administration username and password are assumed to be db2admin.

  1. Start the DB2 command line processor. By default this tool may be started as follows:

    • Linux® or UNIX®:
      • Login as the database administrator (such as: su db2admin)
      • Type db2 and press Enter.
    • Windows®:
      • Select Start => All Programs => IBM DB2 => Command Line Tools => Command Line Processor.
  2. Execute the following code using the command line processor:

    Listing 1. DB2 commands

    Click to see code listing

    Listing 1. DB2 commands

    db2 => CREATE DATABASE EXAMPLE
    db2 => CONNECT TO EXAMPLE USER db2admin USING db2admin
    db2 => CREATE TABLE CUSTOMER(CUST_ID INTEGER NOT NULL, NAME VARCHAR(250), ORDER_ID INTEGER)
    db2 => ALTER TABLE CUSTOMER PRIMARY KEY(CUST_ID)
    db2 => CREATE TABLE ORDER(ORDER_ID INTEGER NOT NULL, STATUS VARCHAR(250), TOTAL INTEGER, CUSTOMER_ID INTEGER)
    db2 => ALTER TABLE ORDER PRIMARY KEY(ORDER_ID)
    db2 => INSERT INTO CUSTOMER(NAME, CUST_ID, ORDER_ID) VALUES ('Roland Barcia', 1, 2)
    db2 => INSERT INTO CUSTOMER(NAME, CUST_ID, ORDER_ID) VALUES ('Geoffrey Hambrick', 2, 1)
    db2 => INSERT INTO ORDER(ORDER_ID, STATUS, TOTAL, CUSTOMER_ID) VALUES (1, 'OPEN', 88, 1)
    db2 => INSERT INTO ORDER(ORDER_ID, STATUS, TOTAL, CUSTOMER_ID) VALUES (2, 'OPEN', 188, 5)
    db2 => ALTER TABLE CUSTOMER FOREIGN KEY(ORDER_ID) REFERENCES ORDER(ORDER_ID)
  3. The CloseOrder example application uses a JNDI context reference to a JDBC datasource to avoid hardcoding of database connection information. Expand CloseOrderWeb and double click Deployment Descriptor: CloseOrderWeb.

  4. Select the Reference tab, then Add... => Resourse reference, and enter or select the field values shown in Figure 9.

    Figure 9. Datsource JNDI context reference
    Figure 9. Datsource JNDI context reference
  5. Enter jdbc/db2/Example for the JNDI name field as shown in Figure 10.

    Figure 10. Datasource JNDI name
    Figure 10. Datasource JNDI name

3. Define XML metadata

To map the database schema to SDO data graphs, mediator metadata must be defined.

Figure 11. O/R mapping
Figure 11. O/R mapping

The metadata can be defined at run time using com.ibm.websphere.sdo.mediator.jdbc.metadata.Metadata, as described very briefly in Figure 7 (see Resources for documentation on defining metadata at run time). Our example, however, defines the metadata in XML. The sample application adds the metadata XML file to the classpath to simplify opening a java.io.InputStream to it, as is required to create a mediator.

  1. In Rational Application Developer, right click the CloseOrderWeb project and select New => Source Folder.

  2. Enter xml for the folder name and select Finish.

  3. Right click CloseOrderWeb then select Java Resources => metadata, then New => other... => Simple => Folder => Next.

  4. Name the folder DAS and select Finish.

  5. Right click the DAS folder and similarly create a new file named metadata.xml.

  6. Insert the following as its contents:

    Listing 2. Add metadata to XML
    <?xml version="1.0" encoding="ASCII" ?>
    <Metadata rootTable="CUSTOMER" xmlns:="http:///com/ibm/websphere/wdo/mediator/rdb/metadata.ecore" >
    	
    	<tables name="CUSTOMER">
    		<columns name="CUST_ID" type="int" />
    		<columns name="NAME" type="string" />
    		<columns name="ORDER_ID" type="int" />
    		<primaryKey columns="CUST_ID" />
    		<foreignKeys columns="ORDER_ID" />
    		<queryInfo filter="( CUST_ID = ? )">
    			<filterArguments name="CUST_ID" type="int" />
    		</queryInfo>
    	</tables>
    
    	<orderBys column="CUSTOMER.NAME" /> 
    	
    	<tables name="ORDER">
    		<columns name="ORDER_ID" type="int" />
    		<columns name="STATUS" type="string" />
    		<columns name="TOTAL" type="int" />
    		<primaryKey columns="ORDER_ID" />
    	</tables>
    	
    	<relationships name="OWNER" oppositeName="ORDER_RELATION" childKey="CUSTOMER" 
    		parentKey="ORDER" exclusive="false" />
    
    </Metadata>

    The O/R mapping of the columns and primary keys should prove to be intuitive. Consider the following descriptions for some of the other metadata tags:

    • <tables rootTable="CUSTOMER">
      An SDO data object graph must define a root or entry point for access. In this application the customer is the root object.

    • <queryInfo>
      This tag defines a filter. If no filter is defined, the metadata is still valid; in that case the mediator returns all customers (and all related orders) as an SDO data object graph. The filter defined here narrows the SDO graph to only the customer that matches the filterArgument. When the mediator retrieves the SDO graph from the database it will require an argument named CUST_ID of type int. Note that the argument does not have name = "CUST_ID", since it can be different from the database column name.

    • <relationships>
      This tag defines the foreign key relationship for CUSTOMER.OPEN_ORDER_ID. In this relationship, customer is the child and order is the parent. "Exclusive" set to false instructs the mediator to fetch all related orders, even those that are not referenced by a customer. If it were set to true, only the orders that have at least one child customer referencing them would be fetched.

    (If you receive a validation error stating Element or attribute do not match QName you can ignore it. Validation within Rational Application Developer will not be setup in this introductory article.)

  7. The example application utilizes a JNDI context reference to lookup the location of the metadata file. This lets the application avoid hardcoded filenames. Expand CloseOrderWeb and double click Deployment Descriptor: CloseOrderWeb.

  8. Select the Reference tab, then Add... => Resourse reference and complete the values as shown in Figure 12.

    Figure 12. Metadata resource environment reference
    Figure 12. Metadata resource environment reference
  9. Enter cell/persistent/string/CloseOrderMetadata for the JNDI name field as shown in Figure 13.

    Figure 13. Metadata JNDI Name
    Figure 13. Metadata JNDI Name

4. Create method

We are now prepared to begin developing the code for the application.

  1. Right click on the CloseOrderWeb project and select New => Class.

  2. Enter developerworks.sdo.example for the package and name it CloseOrderApplication.

To best describe the application, each method of the CloseOrderApplication class is covered individually in the next steps. First is the only public method on the class, closeOrder(), which orchestrates the entire example application (Figure 14).

Figure 14. Sequential events for CloseOrder example application
Figure 14. Sequential events for CloseOrder example application

The following method, which is the entry point to the application, orchestrates nearly every step in Figure 14:

Listing 3. closeOrder method
public void closeOrder(int customerId) {
    ConnectionWrapper conn =
        getConnectionWorker("java:comp/env/jdbc/DASDefault "); [1]
    JDBCMediator mediator = 
        createMediatorWorker("java:comp/env/DAS/XMLMetadata ", conn); [2]

    DataObject order = null;
    try {
        order = getOpenOrderWorker(customerId, mediator); [3]
    } catch (NoCustomer nc) {
        Logger.warn("CloseOrder app could not find specified customer. [4]
            Prompting end user to create one or cancel transaction.", nc);
        // ... code to notify presentation layer would go here ...
    } catch (OrderNotOpen ono) {
        Logger.warn("CloseOrder app could not find order associated with 
            given customer. Notifying end user.", ono); [5]
        // ... same as above ...
    }

    order.set("STATUS", "CLOSED"); [6]
    persistChangesWorker(order, mediator); [7]
    closeConnectionWorker(conn); [8]
}

The primary tasks of this method are:

  1. Get a JDBC connection wrapper.
    The getConnectionWorker() code explains in detail how a connection to a database is made. The worker method requires the JNDI context reference for a JDBC datasource.

  2. Create a mediator.
    The worker method requires the ConnectionWrapper and the JNDI context reference for the location of the metadata.xml file.

  3. Get customer's open order.
    A worker method uses the mediator to fetch the SDO object graph, traverse to the order associated with the root customer, and return it.

  4. Handle exceptional case of No Customer.
    The get open order worker method can throw a NoCustomer exception. In addition to logging the situation and notifying the presentation layer, which is using closeOrder(), typical exception handling may include trying again with a fresh connection or attempting to lookup the customer by name instead of ID.

  5. Handle exceptional case of No Open Order.
    The get open order worker method can throw a OrderNotOpen exception. An appropriate exception handling strategy is left to the reader.

  6. Close the order.
    The status string of the order SDO DataObject is modified.

  7. Order is persisted.
    The order SDO DataObject is persisted to the database.

  8. Connection is closed.
    The database connection is closed.

5. Create a JDBC connection wrapper

The following code sample contains the worker method that creates a database connection. This method covers steps (A) and (B) of the sequence in Figure 14.

Listing 4. getConnectionWorker method
private ConnectionWrapper getConnectionWorker(String ctxRef) {
    Connection conn = null;
    try {
        InitialContext ctx = new InitialContext();
        DataSource ds = (DataSource) ctx.lookup(ctxRef);
        conn = ds.getConnection();
        conn.setAutoCommit(false);
        conn.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
        return ConnectionWrapperFactoryImpl.soleInstance.createConnectionWrapper(conn);
    } catch (NamingException ne) {
        throw new CloseOrderRuntime("CloseOrder could not lookup jdbc string
            binding: "+ctxRef, ne);
    } catch (SQLException sqle) {
        throw new
            CloseOrderRuntime("CloseOrder failed to make database connection", sqle);
    }
}

The contents of this method should be intuitive to a JavaEE developer with JDBC experience. The only code specific to the JDBC DAS is the creation of a ConnectionWrapper from a ConnectionWrapperFactory. Notice that a generic run time exception is used to re-throw exceptions that are assumed to be handled at a higher layer of the JavaEE application.

6. Create a JDBC mediator

The following code sample contains the worker method that creates a mediator. This method covers steps (C) and (D) of the sequence in Figure 14.

Listing 5. createMediatorWorker method
private JDBCMediator createMediatorWorker(String ctxRef, ConnectionWrapper conn) {
    JDBCMediator mediator = null;
    String xmlPath = null;
    try {
        InitialContext ctx = new InitialContext();
        xmlPath = (String) ctx.lookup(ctxRef); <b>[1]</b>
        InputStream is = getClass().getClassLoader().getResourceAsStream(xmlPath); <b>[2]</b>
        mediator = JDBCMediatorFactory.soleInstance.createMediator(is, conn); <b>[3]</b>
    } catch (NamingException ne) { <b>[4]</b>
        throw new CloseOrderRuntime("CloseOrder could not lookup metadata string 
            binding: "+ctxRef, ne);
    } catch (FileNotFoundException fnfe) {
        throw new CloseOrderRuntime("CloseOrder app cannot find: "+xmlPath, fnfe);
    } catch (IOException ioe) {
        throw new CloseOrderRuntime("CloseOrder app has filesystem error", ioe);
    } catch (MediatorException me) {
        throw new CloseOrderRuntime("Metadata inside "+xmlPath+" is invalid.", me);
    }   
    return mediator;
}

The primary tasks of this method are:

  1. Get filename using JNDI context reference.
    The XML metadata filename is retrieved in a similar fashion to the JDBC datasource lookup.

  2. Create a FileStream.
    A conventional java.io.InputStream to the XML metadata file is created using the filename.

  3. Create the JDBC mediator.
    The mediator is created using a JDBCMediatorFactory with the file stream and database connection wrapper as arguments.

  4. Handle Exceptions.
    Again, the various exceptions are handled with a generic run time exception.

7. Retrieve SDO DataObject graph from database

The following code snippet contains the worker method that retrieves the SDO object graph from the datasource and returns the customer's open order. This method covers step (E) of the sequence in Figure 14.

Listing 6. getOpenOrderWorker method

Click to see code listing

Listing 6. getOpenOrderWorker method

private DataObject getOpenOrderWorker(int customerId, JDBCMediator mediator) throws NoCustomer, OrderNotOpen {
    DataObject graph = null;
    try {
        DataObject param = mediator.getParameterDataObject();
        param.setInt("CUST_ID", customerId); [1]
        graph = mediator.getGraph(param); [2]
    }
    catch(MediatorException me) {
        throw new CloseOrderRuntime("CloseOrder app failed to get customer graph from 
            mediator. CUST_ID="+customerId, me);
    }
    
    List cList = graph.getList("CUSTOMER"); [3]
    if(cList.size() == 0) {
        throw new NoCustomer("CloseOrder app could not find customer for 
            CUST_ID="+customerId);
    }
    DataObject customer = graph.getDataObject("CUSTOMER.0"); [4]
    
    if(customer.getInt("ORDER_ID") == 0 || graph.getList("ORDER").size() != 1) {
        throw new OrderNotOpen("CloseOrder app did not find an open [5]
            order for customer with CUST_ID="+customerId);
    }
    
    return customer.getDataObject("ORDER_RELATION"); [6]
}

The primary tasks of this method are :

  1. Create a parameter.
    A parameter called CUST_ID is created and set to customerId. This parameter is used in a filter to narrow the SDO graph to only customers with a specific id as specified in the metadata XML.

  2. Get the SDO DataObject Graph.
    The getGraph method is called on the mediator with the parameter constructed in step 1. This graph should contain a customer and its related order.

  3. Check that customer exists.
    The getList("CUSTOMER") method returns a list of all customer data objects in the SDO graph. If the size is zero, a NoCustomer application exception is thrown.

  4. Get the customer.
    The customer is fetched from the SDO graph. Note that the zero appended to CUSTOMER.0 is necessary to denote which element of the customer list to retrieve (in this case, the list has only one customer).

  5. Check that open order exists.
    If the order is not open, it cannot be closed. The OPEN_ORDER_ID foreign key is checked and the size of the order DataObject list is checked to be non-zero.

  6. The open order is returned.
    The open order is retrieved from the customer sub-graph by traversing the relationship defined in the metadata.

8. Persist the SDO graph

The following code sample contains the worker method which persists the updated SDO DataObject graph. This method covers step (G) of the sequence in Figure 14.

Listing 7. persistChangeWorker method
private void persistChangesWorker(DataObject graph, JDBCMediator mediator) {
    try {
        mediator.applyChanges(graph);
    } catch(MediatorException me) {
        throw new CloseOrderRuntime("CloseOrder app failed to persist SDO graph.              
            Mediator="+mediator+"\nGraph="+graph, me);
    }
}

9. Close the connection

The following code sample contains the worker method which closes the connection to the database. This covers step (H) of the sequence in Figure 14.

Listing 8. closeConnectionWorker method
private static void closeConnectionWorker(ConnectionWrapper conn) {
    try {
        conn.getConnection().close();
    } catch (SQLException sqle) {
        throw new CloseOrderRuntime("CloseOrder app failed to close 
            ConnectionWrapper="+conn, sqle);
    }
}

10. Review application exceptions

CloseOrderApplication uses the following exceptions, which are in the developerworks.sdo.example.exception package:

Listing 9. Exceptions used by CloseOrderApplication
public class CloseOrderRuntime extends RuntimeException {
    public CloseOrderRuntime() {
        super();
    }
    public CloseOrderRuntime(String msg) {
        super(msg);
    }
    public CloseOrderRuntime(Exception nested) {
        super(nested);
    }
    public CloseOrderRuntime(String msg, Exception nested) {
        super(msg, nested);
    }
}

public class NoCustomer extends Exception {
    public NoCustomer() {
        super();
    } 
    public NoCustomer(String msg) {
        super(msg);
    }
}

public class OrderNotOpen extends Exception {
    public OrderNotOpen() {
        super();
    }
    public OrderNotOpen(String msg) {
        super(msg);
    }
}

11. Test the application with a servlet

  1. Right click Deployment Descriptor: CloseOrderWeb project and select New => Servlet....

  2. Enter TestCloseOrder for the Name field and then Next.

  3. Enter developerworks.sdo.example.test for the Java package and then Finish.

  4. Insert the following as the contents of the doGet method:

    Listing 10. Test Servlet
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws 
        ServletException, IOException {
    	String customerId = request.getParameter("customerId");
    	CloseOrderApplication coa = new CloseOrderApplication();
    	coa.closeOrder(Integer.parseInt(customerId));
    	response.getWriter().print("Close order request processed successfully.");
    }
  5. Select the Servers tab, right click on WebSphere Application Server v6.0, then select Start.

  6. Right click the server again and select Add and remove projects... to deploy the CloseOrder EAR project to the server.

  7. Once it is deployed, open the administrative console in a Web browser using this URL: http://localhost:9060/admin.

  8. Select Log in => Security => Global security => JAAS Configuration => J2C Authentication data => New and fill in the form as shown in Figure 15.

    Figure 15. Database authentication entry
    Figure 15. Database authentication entry
  9. Select OK and Save.

  10. Select Environment => WebSphere Variables => DB2UNIVERSAL_JDBC_DRIVER_PATH and enter the directory with your DB2 drivers. The default under Windows is C:\Program Files\IBM\SQLLIB\java.

  11. Select Resources => JDBC Providers => New and fill in the form as shown in Figure 16.

    Figure 16. JDBC Provider configuration
    DB2-Provider.PNG
  12. Press Next, OK, and Save.

  13. Select DB2 Universal JDBC Driver Provider (XA) => Data sources => New.

  14. Insert jdbc/db2/Example for the JNDI name.

  15. Select DB2 Login for Component-managed authentication alias.

  16. Enter EXAMPLE for the Database name.

  17. Enter localhost (or the host for DB2) for Server name and then Save.

  18. To make sure the datasource works, select the box next to DB2 Universal JDBC Driver XA DataSource and press Test connection.

  19. The last administrative step is to setup the JNDI string binding for the location of the metadata.xml file. Select Environment => Naming => Name Space Bindings => New => String => Next and fill out the form as shown in Figure 17. The Name in Name Space value is string/CloseOrderApp/metadata.

    Figure 17. XML filename string binding
    Figure 17. XML filename string binding
  20. Select Next => Finish and Save.

  21. Restart the server to ensure all JNDI bindings are updated.

  22. To run the application, enter the following URL into a Web browser: http://localhost:9080/CloseOrderWeb/TestCloseOrder?customerId=2.


Conclusion

The JDBC Data Access Service provides standardized access to the persistence layer of a service-oriented architecture. This article showcased how a SDO DAS fits into the big picture of enterprise development, and documented the use of concise and user-friendly XML metadata to map an existing database schema to an SDO.

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere, Information Management, Rational, SOA and web services
ArticleID=97460
ArticleTitle=IBM WebSphere Developer Technical Journal: Enabling a service-oriented architecture with SDO and the JDBC Data Access Service
publish-date=10262005