Skip to main content

skip to main content

developerWorks  >  SOA and Web services  >

SOA programming model for implementing Web services, Part 2: Simplified data access using Service Data Objects

developerWorks
Document options

Document options requiring JavaScript are not displayed


Rate this page

Help us improve this content


Level: Introductory

Stephen Brodsky (sbrodsky@us.ibm.com), Senior Technical Staff Member, IBM
Marcia Stockton (mls@us.ibm.com), Senior Technical Staff Member, IBM

28 Jun 2005

Take advantage of Service Data Objects (SDOs) to simplify data access and representation in your service-oriented software. SDOs replace diverse data access models with a uniform abstraction for creating, retrieving, updating, and deleting business data used by service implementations. This is the second article in our series on the programming model for the IBM® Service-Oriented Architecture (SOA).

Service Data Objects

Service Data Objects (SDOs) replace diverse data access models with a uniform abstraction for creating, retrieving, updating, and deleting business data used by service implementations. SDOs (see Service Data Objects 2.0 and Next-Generation Data Programming: Service Data Objects in the Resources section) are a fundamental concept in the IBM Service-Oriented Architecture (SOA). SDOs make developers more productive by freeing them from the technical details of how to access particular back-end data sources, so they can focus principally on business logic (see Integrating relational data into Web applications, Next-generation data programming in the Java™ environment, and Using Service Data Objects with Enterprise Information Integration technology in the Resources section). SDO is a joint specification with BEA Systems, Inc. and used widely in the IBM product line, including WebSphere® Application Server and Rational® Studio tools. Java™ DataBase Connectivity, commonly called JDBC, is a Java interface for executing Structured Query Langauge (SQL) statements. Currently, the programming models for JDBC, Web Services Description Language-defined (WSDL) services, Enterprise JavaBeans (EJBs), and so forth from a service implementation written in Java are similar, but annoying different.

SDOs define a single and uniform way to access and manipulate data from heterogeneous data sources including relational databases, eXtensible Markup Language (XML) data sources, Web services, and enterprise information systems (EIS). They are based on the concept of data graphs. A data graph is a collection of tree-structured objects that might be disconnected from the data source. SDOs are used throughout the application architecture.

Area of application architecture How SDOs are used
SOA
  • SDOs are the input and output of services.
Data access
  • SDOs access relational, XML, EJB, Java Data Objects (JDO), and Hibernate data sources.
  • SDOs are the Data Transfer Objects (DTO) -- also known as Value Objects.
Web services
  • SDOs represent the XML on the wire.
Messaging
  • SDOs represent the messages.
XMLUse SDOs when:
  • XML-enabling an application.
  • Accessing XML files, documents, resources, messages.
Connectors/adapters (EIS, CICS).
  • SDOs represent the data records.
EJB
  • SDOs are DTO (also known as Value Objects).
  • Java 2 Enterprise Edition (J2EE) design pattern.
ADO.NET
  • ADO DataSet is a subset of SDO data graphs.
Enterprise Service Bus (ESB)
  • SDOs are the input and output of services.
Cross-language programming model
  • Complete applications might span tiers and languages.
  • Same programming model for many language skill sets.
Model-driven architecture (MDA)
  • SDO model (Type and Property) is defined by Unified Modelling Language (UML) classes and components.
  • SDO applications follow UML sequence, flow, state, and collaboration.
Java
  • SDOs are smart "plain old Java objects" (POJOs) with POJO interfaces.

In a SOA, an application does not connect to a data source directly. Instead, it accesses an intermediary called a data access service (DAS) and receives a data graph in response. A DAS is a service that handles the technical details for a particular kind of data source. It transforms the data into a SDO graph for the client. The client application interacts with the data graph to get data and change data. To apply an update to the original data source, the application sends the updated graph back to the DAS, which in turn interacts with the data source. In general, the runtime provides the implementations of the DASs, and application development tools provide support for the data graphs.

SDO sidesteps technology churn -- the rewriting of applications to keep up with shifting technology (see Wikipedia in the Resources section) -- by encapsulating data access details to insulate business applications from technology changes. For example, consider a Java Web application designed to read product descriptions from a database and display them as Web pages. To access product descriptions in the database, the application might use JDBC heavily. Suppose that later the application topology changes, placing a Web service between the application and the database. Now the application can no longer use JDBC to access the data and needs substantial rework to substitute a Web service application programming interface (API), such as Document Object Model (DOM) or Java APIs for XML-Based Remote Procedure Call (JAX-RPC). SDO avoids this problem; an application written with SDO need not change.

In addition, SDO offers a metadata API enabling applications, tools, and frameworks to introspect the data model in a uniform way, regardless of its origin. The DAS translates back-end metadata to the standard SDO format.

SDO types can be defined by Java interfaces, XML schema, relational tables and columns, EJBs, COBOL records, messages, or UML (see Catalog of OMG Modeling and Metadata Specifications in the Resources section); implementers can choose a preferred type of system. Simple Java and XML data types are valid SDO data types, saving a step for the Java implementer. SDOs support both dynamic and static data access models, which might be used together. We'll look at these in more detail:

  • The dynamic model (the default) lets programmers get and set data elements in the data graph by name (String). This is particularly useful when the type of the SDO is not known at compile time, or when new properties might be added after the program is deployed. The client program or service queries the SDO to learn its structure and then reads and updates any element by name. For example, one could write a generic SDO-access function and populate it with element-specific metadata in order to access individual SDOs. SDO also uses a subset of XML Path Language (XPath) expressions to enable fast traversal through many DataObjects, for example customer[1]/address/zip to quickly access the zip code of a customer DataObejct.
  • The static model employs named and typed Java interfaces. Each data element has its own individual "getter" and "setter" method. A tool generates static interfaces from SDO Types and Properties.

SDO is important for data representation, even if there is no classic data source in the picture. Examples of this kind of usage include XML messages exchanged with Web services, Java Message Service (JMS) messages, XML files, and many others.



Back to top


Examples

The following examples -- defining a data object containing customer data -- illustrate how easy it is to define SDOs and use them, using either Java or XML. Example 1 (in XML) is the basis for the SDO type.


Example 1. An SDO type definition in XML
				
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
                xmlns:tns="http://www.myvalue.com"
		targetNamespace="http://www.myvalue.com">
	<element name="customer" type="Customer"/>
	<complexType name="Customer">
		<sequence>
			<element name="customerID" type="string"/>
			<element name="firstName" type="string"/>
			<element name="lastName" type="string"/>
			<element name="stockSymbol" type="string"/>
			<element name="stockQuantity" type="int"/>
		</sequence>
	</complexType>
</schema>

The Java interface in Example 2, generated from the preceding XML, illustrates the use of static interfaces.


Example 2. An SDO type definition in Java
				
public interface Customer {
	String getCustomerID();
	void setCustomerID(String customerID);
	String getFirstName();
	void setFirstName(String firstName);
	String getLastName();
	void setLastName(String lastName);	
        String getStockSymbol();
	void setStockSymbol(String stockSymbol);
	int getStockQuantity();
	void setStockQuantity(int stockQuantity);
}

Once the SDO type has been defined, you can instantiate it (allocate storage for the data objects) by passing the type definition to the SDO data factory. The factory is simply a component of the runtime whose function is to instantiate SDO data objects from SDO type definitions.

Example 3 and Example 4 show how to create an SDO by passing XML schema namespace and complex type name (defined in Example 1) or the Java interface class (defined in Example 2) as the argument, respectively.


Example 3. SDO creation with XML Schema namespace and complex type name argument
				
DataObject customer = DataFactory.INSTANCE.create("http://www.myvalue.com", "Customer");



Example 4. SDO creation using SDO DataFactory with Java interface class argument
				
Customer customer = (Customer) DataFactory.INSTANCE.create(Customer.class);

After the SDO has been instantiated, the implementation can access it. The code samples in Example 5 and Example 6 show dynamic and static access to the Customer SDO, respectively.


Example 5. Dynamic access to SDO
				
DataObject customer = ... ;
customer.setString("customerID", customerID);
...
customer.setInt("stockQuantity", 100);
String customerID = customer.getString("customerID");
...
int stockQuantity = customer.getInt("stockQuantity");



Example 6. Static access to SDO
				
Customer customer = ... ;
customer.setCustomerID(customerID);
...
customer.setStockQuantity(100);
String customerID = customer.getCustomerID();
...
int stockQuantity = customer.getStockQuantity();

We further illustrate the simplicity of the programming model promoted by SDOs with examples of access to an XML file service and to a relational database. Note how these applications are similar, despite technology differences. The application developer can focus on business logic and let the service handle the implementation details of updating a persistent data store.

Example 7. An XML file service

This simple example loads data from an XML file into an SDO data graph, prints and updates the data, then writes it back to a file. (The business goal is to change "Adam" to "Kevin".)

Define the XML file to be read as a root customers data object corresponding to the root XML element and a many-valued customer property. Customers contains one data object for each customer element in the XML file. Each customer has two properties: SN and firstName.
<customers xmlns="http://customers.com">
	<customer SN="1" firstName="Adam" />
	<customer SN="2" firstName="Baker" />
</customers>

Read the file data.
DataObject root = xmlService.load(InputStream);

Walk through the list of customer data objects and print the first name for each.
Iterator i = root.getList("customer").iterator();
while (i.hasNext()) {
	DataObject cust = (DataObject) i.next();
	String name = cust.getString("firstName");
	System.out.println(name);
}

Set the firstName property of the first customer data object to Kevin. The middleware updates the change summary (not shown) to indicate what data was changed.
DataObject customer1 = root.getDataObject("customer[1]");
customer1.setString("firstName", "Kevin");  // or

root.setString("customer[1]/firstName", "Kevin");


Write the data objects to the file.
xmlService.save(OutputStream, root);

The result is an updated XML document.
<customers xmlns="http://customers.com">
  <customer SN="1" firstName="Kevin" />
  <customer SN="2" firstName="Baker" />
</customers>

Example 8. Access to a relational database

Although complex relational to SDO mappings are possible, this example uses a very simple one: each database table is an SDO type, each row in the table is an SDO data object, and each column is an SDO property. The application logic is the same: read from the database by executing a predefined query, print and update the data (change "Adam" to "Kevin"), and save the changes to the database. The database query returns two rows from the CUSTOMER table:

CUSTOMER ID (int, primary key)CUSTOMER FIRSTNAME (String)CUSTOMER LASTNAME (String)
1 Adam Smith
2BakerStreet

The SDO implementation is given below with explanations.

The rdbService queries to obtain data from the database.
DataObject root = rdbService.get(); 

The same data could have been equivalently expressed in XML.
<customers>
  <CUSTOMER ID="1" FIRSTNAME="Adam" LASTNAME="Smith"/>
  <CUSTOMER ID="2" FIRSTNAME="Baker" LASTNAME="Street"/>
</customers>

Print each customer's first name.
Iterator i = root.getList("CUSTOMER").iterator();
while (i.hasNext()) {
	DataObject cust = (DataObject) i.next();
	String name = cust.getString("FIRSTNAME");
	System.out.println(name);
}

Set the FIRSTNAME of the first data object to Kevin. The middleware updates the change summary (not shown) to indicate the change.
DataObject customer1 = root.getDataObject("CUSTOMER[1]");
customer1.setString("FIRSTNAME", "Kevin"); // or

root.setString("CUSTOMER[1]/FIRSTNAME", "Kevin"); 

Write the updated data to the database.
rdbService.update(root);

Now the database contains:

CUSTOMER ID (int, primary key)CUSTOMER FIRSTNAME (String)CUSTOMER LASTNAME (String)
1 Kevin Smith
2BakerStreet

Note that row 1 has been updated.

What if another application had accessed the database and changed values after our example application had obtained its data graph? On a write, the data access service examines the change summary to determine how to apply that update to the data source. The database can use optimistic concurrency control to ensure that the database last contained the value "Adam" prior to this change (otherwise, another application might have changed the data first, possibly requiring some error recovery in the application). Some services implement more advanced forms of optimistic concurrency; the change history provides the original values needed for those algorithms.

When using EJBs, SDOs play the role of the DTO (also called Value Object) J2EE design pattern. Typically, access to each property of an Entity EJB is very expensive, so transferring several SDO objects in a data graph is more efficient. A Session EJB might have methods to produce and consume a graph of SDOs with more efficient direct access to the entity EJBs. Customer Entity EJBs encapsulate the database access for Customer records. A Session EJB provides access methods to produce and return a graph of Customer SDOs from the Customer Entity EJBs.


Example 9. Session bean interface to return SDOs and update entity EJBs from SDOs
				
public interface CustomerSession {
	Customer getCustomerByID(String customerID);
	Customers getCustomersByLastName(String lastName);
	void updateCustomers(Customers customers);
}

Customers is the SDO root Data Object that contains several customers. The List of Customers contains Customer Data Objects. The ChangeSummary is used to record all the changes made to the Customer objects, including any additions, delations, or updates. The updateCustomers() method updates the Customer Entity EJBs with the changes and can batch the changes to the data sources in a transaction.


Example 10. An SDO Type Definition of Customers in Java
				
public interface Customers {
	List<Customer> getCustomers();
	ChangeSummary getChanges();
}



Back to top


Summary

SDOs enable uniform access to application data and a common programming model for all data sources, wherever and however the data is stored. SDOs leverage the simplicity of XML without introducing the complexity of XML Schema or the performance issues of serialization. Using SDOs and SOA together, systems programming tasks are separated from the business logic and encapsulated in reusable services, instead of skills every programmer needs to know to get started. They simplify business application programming without getting pulled into technology or implementation details, protecting against technology churn. With SDOs, business applications are what they were meant to be: business applications.



Resources



About the authors

Stephen Brodsky

Stephen A. Brodsky, Ph.D., is a Senior Technical Staff Member at the IBM Silicon Valley Laboratory. He has led or contributed to numerous software architectures, products, and standards, including Service Data Objects (SDO), the IBM SWG Architecture Board SOA BluePrint, WebSphere and Rational Server and Studio products, the Eclipse Modeling Framework (EMF), UML, MOF, and XMI (XML Metadata Interchange). He has also co-authored a book on XMI. He holds a dozen patents on object technology and is a member of several SWG AB workgroups. You can contact Stephen at sbrodsky@us.ibm.com.


Author photo

Marcia L. Stockton is a Senior Technical Staff Member and Master Inventor with the IBM Software Group in Research Triangle Park, North Carolina (residing in California). She is also a senior IEEE member. Marcia leads the Software Group Architecture Board's Programming Model Workgroup, where she drives horizontal integration initiatives and promotes programming model simplification across Lotus®, Rational, WebSphere, DB2®, and Tivoli® products. Her 73 filed U.S. patents range from networking, Web, security, privacy, multimedia, wireless, pervasive devices, to radio frequency ID. She recently led efforts to define the architecture for identity management and for edge server distributed programming. She joined IBM in 1988 after five years developing networking software. She earned a B.A. from Swarthmore College in 1975. You can contact Marcia at mls@us.ibm.com.




Rate this page


Please take a moment to complete this form to help us better serve you.



 


 


Not
useful
Extremely
useful
 


Share this....

digg Digg this story del.icio.us del.icio.us Slashdot Slashdot it!



Back to top


Java and all Java-based trademarks and logos are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both. Microsoft is a trademark of Microsoft Corporation in the United States, other countries, or both. Other company, product and services names might be trademarks or service marks of others. Other company, product, or service names may be trademarks or service marks of others.