Next in thread → Next in month →

Re: [sdo] ISSUE 125: Key Property Proposal

From
Bryan Aupperle <>
Date
2008-05-29T14:20:45+00:00
ID
Thread
Re: [sdo] ISSUE 125: Key Property Proposal
One additional question -

In SalesRepType you have the
property orders, which today is effectively a list of pointers to
the actual order data objects.  Does this change with the use
of keys?  I.e. would this now be a list of keys which has to be resolved
when navigating to the order data objects?  The corresponding
XSD suggests this, but it is not clear if that is what you have in mind
for the in-memory representation.

Bryan Aupperle, Ph.D.

STSM, WebSphere Enterprise Platform Software Solution Architect

Research Triangle Park,  NC 

+1 919-254-7508 (T/L 444-7508)

Internet Address: 

"Barack, Ron"
<> 

05/22/2008 07:57 AM

To

<>

cc

Subject

[sdo] ISSUE 125:  Key Property
Proposal

Hi Everyone, 

Let me make some proposals regarding keys.
 I believe this approach to be consistent with:

Oracle's approach

The current conception of key's in the DAS
WG (as represented by Christophe's mail)

The current (2.1) use of xs:ID and xs:IDREF

JPA.  

Use Cases for Keys and Projection

We begin with a motivating use case.

Domain models tend to be larger and complex
than the views used by individual clients.  Moreover, when going from
a large server-side model, it is necessary to define the scope of the data
which should be transmitted to a remote client.  The boundaries of
the data which should be transmitted in a single  packet must somehow
be defined.  On the other hand, the door must be left open for clients
to further explore the model in succeeding calls to the server.

Imagine a service that returns an Employee
object.  In the domain model, Employee has a refence to Department,
and Department in turn has a list of all Employees.  If we define
the transmission packet to be the transient closure reachable from Employee,
then we can never send a single employee, we will always send the complete
list of employees in the department.

Our approach is to use keys to represent the
boundary points in a transmission packet.  It is assumed that clients
that wish to explore the model beyond these boundaries will be able to
use the keys to somehow perform lookups, but the API through which this
is done is out-of-scope for SDO (being more of a DAS issue).

In the example, we can imagine that the server
has a SDO type system in which Employee has a property with type Department.
 In the client's type system, however, the corresponding property
has type {commonj.sdo}string.  This value would represent the identity
of the Department.  The basic functionality we wish to achive  is
to allow projection between these two HelperContexts.

Types, Key Properties, and KeyTypes

We need to define the following open content
(global) properties. 

     sdo:key    
               boolean    
                   (used
on properties) 

     sdo:keyType              
 commonj.sdo.Type      (used on types)

     sdo:embeddedKey    boolean      
                 (used on
properties) 

The sdo:key property can be set to true on
properties under only when isMany=false and either of the following is
true 

a) the type of the property is a dataType,
but not float, double or any other “approximate” type.

b) the type of the property is not a dataType, but itself defines one or
more key properties. 

A property marked with sdo:key=true is called
a key
property. 

Any type with at least one key property is
said to have a key
type.  If there is exactly one key property, then if the type
of the key property is a dataType, then the key type is the type of the
key property.  If there is exactly one key property and the key property
is not a dataType, then the key type is the key type of the key property’s
type.

  

If a type contains more than one key property then the type must have the
sdo:keyType property set.  The value of this property must be a type
such that for every key property, the key type also contains a property
with the same name.  If the key property is a dataType, then the corresponding
property in the keyType must have the same type as the key property.  If
the key property is not a dataType, then the type of the corresponding
property is the key type associated with the key property’s type.

Example: 

OrderType 

-- id                   string
sdo:key=”true” 

-- customer                  
  CustomerType 

-- lineItems                  
 LineItemType many=”true” 

LineItemType 

-- order                  
     OrderType sdo:key=”true” sdo:opposite=”lineItems”

-- lineNumber           int sdo:key=”true”

-- item                 ItemType

LineItemKeyType 

-- order                  
     string 

-- lineNumber           int

When the types are defined through XSD, an
attribute with type “xs:ID” generates a string property with sdo:key=”true”.

Some DataObjects may wish to use their composite
key type directly as a property.  The embeddedKey annotation is used
in this case. For instance, LineItemType may also be defined

LineItemType 

-- lineItemKey          LineItemKeyType sdo:embeddedKey=”true”
containment=”true” 

-- item                 ItemType

Sdo:EmbeddedKey cannot be used in combination
with sdo:key, and can only be used on containment properties.

Generating XSD from Types using Keys 

When generating XSD from an SDO type, non-containment references to keyed
types generate elements or attributes whose type correspond to the key
type of the referenced object.  If the key type is a dataType and
the reference is single-valued, the reference is rendered as attributes.
 If the key type is complex, or the reference is multivalued, the
reference is rendered as a element.  In either case, the implementation
must annotate the attribute or element with “sdox:propertyType”.

For instance, let us extend our previous example,
adding SalesRepType, representing the SalesRepresentative that is responsible
for the order.  

SalesRepType 

-- name                 string

-- employeeId           string, sdo:key=”true”

-- orders                  
    OrderType, many=”true”, containment=”false”

This generates the following XSD.  

       
<xs:element
name="SalesRepType">

                <xs:complexType>

                    
   <xs:sequence>

                    
           <xs:element
name="name"
type="xs:string"/>

                    
           <xs:element
name="employeeId"

                    
               type="xs:string"
sdo:key="true"
/>

                    
           <xs:element
name="orders"

                    
               type="xs:string"

                    
               maxOccurs="unbounded"

                    
               sdox:propertyType="tns:OrderType"/>

                    
   </xs:sequence>

                </xs:complexType>

        </xs:element>

If SalesRepType had a multivalued reference
to LineItemType instead of a reference to orders, this would look like

       
<xs:element
name="SalesRepType">

                <xs:complexType>

                    
   <xs:sequence>

                    
           <xs:element
name="name"
type="xs:string"/>

                    
           <xs:element
name="employeeId"

                    
               type="xs:string"
sdo:key="true"
/>

                    
           <xs:element
name="lineItems"

                    
               type="tns:LineItemKeyType"

                    
               maxOccurs="unbounded"

                    
               sdox:propertyType="tns:LineItemType"/>

                    
   </xs:sequence>

                </xs:complexType>

        </xs:element>

If the reference to OrderType was single valued:
 

       
<xs:element
name="SalesRepType">

                <xs:complexType>

                    
   <xs:sequence>

                    
           <xs:element
name="name"
type="xs:string"/>

                    
           <xs:element
name="employeeId"

                    
               type="xs:string"
sdo:key="true"
/>

                    
           <xs:element
name="orders"

                    
               type="xs:string"

                    
               maxOccurs="unbounded"

                    
               sdox:propertyType="tns:OrderType"/>

                    
   </xs:sequence>

                    
           <xs:attribute
name="order"

                    
           type="xs:string"
sdox:propertyType="tns:OrderType"/>

                </xs:complexType>

       
                     
                     
                     
                     
         

        </xs:element>

Question:  How do composite
keys affect the XML representation of changeSummary?  For now, I would
say we should continue to use only the IDREF or AnyURI representation of
references, not the key.  I believe that the DAS group will anyway
request fundamental changes to ChangeSummary’s XML, and I wouldn’t want
to hold up this proposal waiting for such changes.

Keys and Projection

A type and its keyType are compatible with
each other.  This means that a projection may use the keyType directly
as a property type.  For instance, we may define a context in which
the SalesRepType is defined as 

SalesRepType 

-- name                 string

-- employeeId           string, sdo:key=”true”

-- orders                  
    string, many=”true” 

Unlike normal projection, when complex DataObjects
are projected onto keyType, there is no association that the original object
and its projection represent the same underlying data.  For instance,
imagine that in one HelperContext, EmployeeType has a reference to DepartmentType,
and that DepartmentType has a key type of {commonj.sdo}string.  In
another context, instead of the reference to DepartmentType, the corresponding
property could have type string.   If we project an instance of EmployeeType
into from the first context into the second context, and in the second
context change the value of the department property, then this
does not indicate that the
DepartmentType object in the original context should have the value of
its key property changed, rather, that a different department should be
referenced.

When projecting from a keyType object to the
associated complex data object, the default behavior is to create an object
with only key properties filled.  This behavior may be customized
by associating a resolver with the type.  We define an interface

        public
interface KeyResolver { 

                DataObject
resolve(Object key); 

            } 

and an open content property

           
sdo:resolver                Class

This property is meant to be associated with
types, and the value of the property must have a no-arg constructor, and
must implement KeyResolver.

When projecting from a key object to a DataObject,
the system must check if a KeyResolver has been specified for the target
type.  If so, the value of the key is passed to an instance of the
KeyResolver class, and the returned object is used as the projection of
the key.
Next in thread → Next in month →