Skip navigation.
Downloads | Product Documentation | Support

Concepts Guide

# Using Service Data Objects (SDO)

This section describes the Liquid Data client-side application programming object model, Service Data Objects (SDO). The following topics are covered:

- Introducing SDO
- Getting Data Objects
- A First Look at SDO
- Data Updates

# Introducing SDO

SDO is a Java-based data programming model and architecture for accessing and updating data. SDO is defined in a joint specification proposed by BEA and IBM (JSR 235). SDO is intended to give applications an easy-to-use, uniform programming model for accessing and updating data, regardless of the underlying source or format of the data.

Unlike existing data access technologies such as JDO or JDBC, SDO specifies both a static and a dynamic interfaces for accessing data. The static (or strongly typed) interface gives client developers an easy-to-use, update-capable model for accessing values. A static interface function is in the form:

>     	getCUSTOMERNAME()

As implied by the sample function name, to use the static interface the developer must know the types of the data (that is, CUSTOMERNAME) at development time. If the types are unknown at development time, the developer can use the dynamic (or loosely typed) interface. Such calls are in the form:

>     	cust.get("CUSTOMERNAME")

A dynamic interface is useful when the data type is not known or defined at development time and is particularly useful for creating programming tools and frameworks across data source types.

In addition to a programming interface, SDO defines a data programming architecture. A component of this architecture called the mediator serves as the adapter between the client and data source. A mediator specializes in exchanging data with the data source. It knows how to retrieve data from a particular source and pass changes back to it. Data is passed in a datagraph, which consists of a graph of data objects.

As mentioned in the SDO specification, a particular SDO implementation is likely to have mediators intended that are specialized for a particular source type, such as for databases. Liquid Data provides a data service mediator that resides between SDO clients and the data integration layer.

With SDO, clients use data in an essentially stateless, disconnected fashion. When Liquid Data gets data from a source, such as a database, it acquires one or more database connections only long enough to retrieve the data. Once the data is acquired, Liquid Data releases the connections. The client works on a local copy of the data, disconnected from the data source.

Disconnected data programming means that the client can operate on the data without generating additional network traffic. The network is accessed again only when the client wants to apply the data changes to the source. Disconnected data access contributes to a scalable, efficient computing environment because back-end system resources are never tied up for very long.

Optimistic concurrency rules are used to ensure the integrity of data when updates occur. With optimistic concurrency, data at the data source is not locked while a client works with it. Instead, if updates are made to the data, potential conflicts (such as other clients changing the same data after the client got it) are detected when the updates or propagated back to the sources.

For complete information on Service Data Objects, including the specification and Javadoc, go to:

http://dev2dev.bea.com/technologies/commonj/sdo/index.jsp

# Getting Data Objects

Liquid Data uses SDO as its client-side programming model. Simply put, this means that when a Java client invokes a data service's read function—either through the Liquid Data Mediator API or through the Workshop Control—it gets a return value in the form of an SDO data object. A data object is the fundamental component in the SDO programming model. It represents a unit of structured information, with static and dynamic interfaces for getting and setting its data values.

Once the data is acquired, the client works on it in disconnected fashion. It passes the changed data back to data access layer only if it wants to save the changes to the back-end data source.

# A First Look at SDO

This section introduces you to SDO programming through a small code sample. The sample shows how SDO provides a simple, easy to use client-side data programming model.

The sample is written against the data service shown in Figure 6-1.

Figure 6-1 Data Service Design

The data type for the Customer data service is CUSTOMER. A data type is a structured XML document, in this example composed of properties such as customer ID, name, and orders. The data for a CUSTOMER instance comes from four other data services, CUSTOMERS.ds, PO_CUSTOMERS.ds, PO_ITEMS.ds, and getCustomerCredit.ds (although the details of the composition of the data service do not need to be of concern to the data service user).

The sample Customer data service has several methods for getting data type instances, including `getCustomer()`, `getCustomerById()`, `getPaymentList()`, and so on. The function `getPaymentList()` is a navigation function. It does not return a CUSTOMER document; instead it returns data from a data service for which a logical relationship has been defined. In the case of `getPaymentList()`, the related data service named PAYMENTS returns the payment history for a given customer.

The navigation function makes it easy for client applications to acquire additional related data that is likely to be of interest when working with CUSTOMER documents. With the same data service handle used to get a customer, they can get that customer's list of payments.

The result is code that is concise and readable and easy to maintain, as shown in the following snippet.

Listing 6-1 SDO Sample

>     import java.util.Hashtable;
>     import javax.naming.Context;
>     import javax.naming.InitialContext;
>     import com.bea.ld.dsmediator.client.*;
>     import org.openuri.temp.schemas.customer.CUSTOMERDocument;

>     public class myCust {
>        public static void main(String[] args) throws Exception {
>           Hashtable h = new Hashtable();
>           h.put(Context.INITIAL_CONTEXT_FACTORY,
>           "weblogic.jndi.WLInitialContextFactory");
>           h.put(Context.PROVIDER_URL,"t3://localhost:7001");
>           h.put(Context.SECURITY_PRINCIPAL,"weblogic");
>           h.put(Context.SECURITY_CREDENTIALS,"weblogic");

>           DataService ds = XmlDataServiceFactory.newXmlService(
>                     new InitialContext(h),
>                     "Demo",
>                     "ld:DataServices/Customer");
>           Object arg[]={new Integer("987655")};
>           CUSTOMERDocument myCustomer =
>                     (CUSTOMERDocument) ds.invoke("getCustomer",arg);
>           myCustomer.getCUSTOMER().setCUSTOMERNAME("BigCo, Inc");
>           ds.submit(myCustomer,"ld:DataServices/Customer");
>           System.out.println(" Customer information: \n" + myCustomer);
>        }
>     }

Notice that once the proper packages have been imported and the initial context to the server has been made, in about five lines of code the client application:

- Gets data from ultimately four different data sources.
- Modifies a value (customer name).
- Submits the change to Liquid Data, which propagates the change back to the data sources.

The complexity of this entire procedure is hidden from the client application developer. Instead, the complexity is handled at the data services layer and by the Liquid Data framework.

# Data Updates

As it does for reading data, SDO gives client applications a unified interface for updating data. With Liquid Data, client application can modify and update data from heterogeneous, distributed sources as if the data were from a single entity. The complexity of propagating changes to diverse data sources is hidden from the client programmer. With a single update call, a client can propagate changes to a variety of data sources.

Data source updates occur in a transactionally secure manner; that is, given an update call that affects multiple sources, all updates to individual data sources within the update call either succeed or fail together. (Note that it is possible to override this behavior if needed.)

From the data service implementor's point of view, the task of building a library of update-capable data services is considerably eased by the Liquid Data update framework. For relational sources, Liquid Data can often propagate changes to the data sources automatically. For other sources, or to customize relational updates, you can use the Liquid Data update framework and tools to quickly implement a wide range of update-capable services.

As shown in the Figure 6-2, updates occur through a process in which the requested change is first analyzed to determine, among other things, the lineage of the data. The Liquid Data mediator then decomposes the submitted object into its constituent parts and propagates the changes to the data source.

At any point in this process, you can have your own code programmatically intervene, for example, to validate the update values or for auditing purposes.

For more information on updates, see the Liquid Data Application Developer's Guide.

Figure 6-2 Liquid Data Source Updates