Service Data Objects (SDO) [1] is a specification for a programming model that unifies data programming across data source types, provides robust support for common application patterns, and enables applications, tools, and frameworks to more easily query, view, bind, update, and introspect data. This white paper discusses the motivation behind SDO, presents the SDO architecture and discusses opportunities for further enhancements by vendors in the industry.
Service Data Objects (SDO) 是一种编程模型的规范,它统一了访问不同类型数据源时的数据编程,为常见应用模式提供全方位的支持,允许应用、工具和框架等更加容易的查询、展示、绑定、更新和检索数据。
Data Objects often have typed Java interfaces. However,sometimes it is either impossible or undesirable to create Java interfaces to represent the Data Objects. One common reason for this is when the data being transferred is defined by the output of a query. Examples would be:
A relational query against a relational persistence store.
An EJBQL queries against an EJB entity bean domain model.
Web services.
XML queries against an XML source.
In these situations, it is necessary to use a dynamic store and associated API. SDO
has the ability to represent Data Objects through a standard dynamic data API.
In cases where metadata is known at development time (for example, the XML Schema definition or the SQL relational schema is known), SDO supports code-generating interfaces for Data Objects. When static data APIs are used, the dynamic data APIs are still available. SDO enables static data API code generation from a variety of metamodels, including:
Popular XML schema languages.
Relational database schemas with queries known at the time of code
generation.
Web services, when the message is specified by an XML schema.
JCA connectors.
JMS message formats.
UML models
While code-generation rules for static data APIs is outside the scope of this core
SDO specification, it is the intent that SDO supports code-generated approaches
It is common to have to deal with “complex” or “compound” Data Objects. This is the case where the Data Object is the root of a tree, or even a graph of objects. An example of a tree would be a Data Object for an Order that has references to other Data Objects for the Line Items. If each of the Line Items had a reference to a Data Object for Product Descriptions, the set of objects would form a graph. When dealing with compound data objects, the change history is significantly harder to implement because inserts, deletes, adds, removes and re-orderings have to be tracked, as well as simple changes. Service Data Objects support arbitrary graphs of Data Objects with full change
It is a common pattern for a client to receive a Data Object from another program component, make updates to the Data Object, and then pass the modified Data Object back to the other program component. To support this scenario, it is often important for the program component receiving the modified Data Object to know what modifications were made. In simple cases, knowing whether or not the Data Object was modified can be enough. For other cases, it can be necessary (or at least desirable) to know which properties were modified.Some standard optimistic collision detection algorithms require knowledge not only of which columns changed, but what the previous values were. Service Data Objects support full change summary.
SDO provides navigation capabilities on the dynamic data API. All Data Objects are reachable by breadth-first or depth-first traversals, or by using a subset of XPath 1.0 expressions.
Many applications are coded with built-in knowledge of the shape of the data being returned. These applications know which methods to call or fields to access on the Data Objects they use. However, in order to enable development of generic or framework code that works with Data Objects, it is important to be able to introspect on Data Object metadata, which exposes the data model for the Data Objects. As Java reflection does not return sufficient information, SDO provides APIs for metadata. SDO metadata may be derived from:
Supports validation of the standard set of constraints captured in the metadata. The metadata captures common constraints expressible in XML Schema and relational models (for example, occurrence constraints).
Provides an extensibility mechanism for adding custom constraints and validation.
An important special case of constraints is the ability to define relationships between objects and to enforce the integrity of those constraints, including cardinality, ownership semantics and inverses. For example, consider the case where an employee has a relationship to its department and a department inversely has a list of its employees. If an employee’s department identifier is changed then the employee should be removed, automatically, from the original department’s list. Also, the employee should be added to the list of employees for the new department. Data Object relationships use regular Java objects as opposed to primary and foreign keys with external relationships.
Support for containment tree integrity is also important.
While the Java™ platform and J2EE provide a variety of data programming models and APIs, these technologies are fragmented and are not always amenable to tooling and frameworks. Further, some of the technologies can be hard to use and may not be sufficiently rich in functionality to support common application needs. SDO is intended to create a uniform data access layer that provides a data access solution for heterogeneous data sources in an easy-to-use manner that is amenable to tooling and frameworks. SDO is not motivated by a need to replace lower-level data access technologies (see Relationship to Other Technologies below). SDO has the following goals:
Unified data access to heterogeneous data sources. Current data programming technologies are more or less specific to data source types. In real-world applications, however, data frequently comes from a variety of sources, including relational databases (accessed through JDBC [2], Entity EJB [3], or other persistence frameworks), custom data access layers (implemented with well-known design patterns), Web services (accessed through JAX-RPC [4] or some other means), XML data stores, JMS [5] messages, and enterprise information systems (accessed through JCA [6] Resource
Adapters or via some custom APIs). This heterogeneity poses a significant challenge for application developers because of the broad diversity of programming models they need to learn and use. The plethora of data access APIs is an even more significant challenge for tools and frameworks that attempt to automate many common data programming tasks, such as binding UI components to back-end data sources (e.g., JSR-227 [7]). Thus, a common facility for representing collections of data regardless of data source type can provide a simpler, unified programming model for the application programmer, as well as providing new opportunities for tools and frameworks to work across heterogeneous data sources consistently.
Unified support for both static and dynamic data APIs. Static, strongly typed interfaces provide an easy to use programming model for application programmers. For example,Entity EJBs, JDO [8], Hibernate [9], and other object/relational persistence mechanisms provide typed Java interfaces to data that provides a convenient programming model to developers (e.g., account.getFirstName() or account.getBalance()). JDBC’s ResultSet and RowSet interfaces, in contrast, provide only dynamic, untyped data APIs (e.g., rs.getString(“FIRST_NAME”) or rs.getFloat(“BALANCE”)). Similarly, JAXB [10] provides code-generated Java interfaces to XML data, which makes XML data programming much simpler than using the DOM or SAX APIs.Neither static nor dynamic data APIs alone are sufficient, however: both are necessary. Static data APIs provide the ease-of-use application programmers needs. But in some
cases, static Java interfaces for data is neither feasible nor desirable. For example, dynamic queries where the shape of the resulting data is not known a priori, static Java interfaces for the data is not feasible. Thus, a unified data programming technology needs to support both static and dynamic data APIs seamlessly.
Support for tools and frameworks. Current data programming technologies are not amenable to tools and frameworks across data source types. Tools and frameworks require several key features:
• Uniform access to data across heterogeneous sources. As real-world applications use data from a variety of sources, frameworks need to rely on a uniform data representation.
• Dynamic data APIs. As discussed above, it is much more appropriate for
frameworks to use dynamic data APIs, as frameworks are generic to particular
data and code-generated interfaces are often inappropriate or not feasible.
• Simple introspection (or metadata) APIs. Frameworks commonly need to
introspect the “shape” of data in order to perform data rendering, updateable forms, data binding, etc.
Support for disconnected programming models. Many applications naturally have a disconnected usage pattern of data access: an application reads a set of data, retains it locally for a short period of time, manipulates the data, and then applies the changes back to the data source. For example, this is a very common pattern in Web-based applications: a Web client requests to view a form, a Servlet or JSP requests data in a local read transaction and renders the data in an HTML form, the Web client submits updates to a form, and the Servlet or JSP uses a new transaction to update the data. Best
practice typically dictates that optimistic concurrency semantics be used for this scenario, which provides for high levels of concurrency with the appropriate business-level semantic. There is no data access technology today that provides this disconnected, optimistic model in conjunction with the other features described above. Extensions to JDBC (through the CachedRowSet in JSR-114, “RowSet Implementations” [11]) provide the disconnected model, but as mentioned earlier, JDBC does not meet the requirements of heterogeneous data access or ease-of-use. Similarly, many Object/Relational persistence mechanisms (e.g., many Entity EJB implementations, JDO, Hibernate, etc.) support optimistic concurrency semantics, but they do not provide the necessary universal data access features.
Support for custom data access layers based on common design patterns. Many applications use well-known design patterns (e.g., Transfer Object [12], Transfer Object Assembler [13], Data Access Objects [14], and Domain Store [15]) to build custom data access layers. These patterns are commonly used when the application needs to be insulated from the physical data sources. Implementing data access layers commonly requires a significant amount of custom code, much of which can be automated. Further,these custom data access layers should be able to be integrated into tools and frameworks.
支持基于常见设计模式的客户数据访问层。许多应用使用众所周知的设计模式(比如Transfer Object、Transfer Object Assembler, Data Access Objects, 和 Domain Store)来构建客户化的数据访问层。这些模式在那些要求应用和物理数据源无关时经常被使用。实现这种客户数据访问层通常需要非常多的客户化代码,其中的一些代码可以被自动化生成。而且,这些客户化数据访问层必须可以被工具和框架集成。
Decouple application code from data access code. In order to be reusable and
maintainable, application code should be separable from data access. Data access technologies should be amenable to this separation of concerns.
SDO(Service Data Object)为我们提供了统一的数据应用开发框架,它提供了对多种企业信息系统 (EIS) 的统一的数据访问,包括数据库、遗留应用程序(使用 JCA)、XML 或者是 Web 服务数据源。SDO 为业务数据提供了一种中立的表示方法,建立了一种与数据源无关的模型,降低了耦合度.