Adobe® LiveCycle® Data Services ES 2.6 Developer Guide

General Data Management Service configuration

Some aspects of configuring Data Management Service destinations apply to most destinations, and others are determined by the particular data adapter that a destination uses. This section describes general configuration for Data Management Service destinations.

Configuring paging

The enabled attribute of the paging element indicates whether data paging is enabled for the destination. When you enable paging, the pageSize attribute indicates the number of records to be sent to the client when the client-side DataService.fill() method is called. This element is optional; the default value is false.

On the client side, the mx.data.DataService class provides methods for removing pages of data when dealing with large data sets. For more information, see Data paging.

The following example shows a paging element in a destination definition:

...
    <destination id="contact">
        <properties>
...
                <network>
                    <paging enabled="true" pageSize="10"/>
                </network>
    ...
        </properties>
    </destination>
...

Using transactions

By default, LiveCycle Data Services ES encapsulates client-committed operations in a single J2EE distributed transaction. All client data changes are handled as a unit. If one value cannot be changed, changes to all other values are rolled back. Distributed transactions are supported as long as your Java 2 Enterprise Edition (J2EE) server provides support for J2EE transactions (JTA).

The boldface text in the following example shows the use-transactions property set to true (the default value) at the service level so that it applies to all Data Management Service destinations:

...
<service id="data-service" class="flex.data.DataService">
...
    <properties>
        <use-transactions>true</use-transactions>
    </properties>
</service>
...

If you set the use-transactions property to false, each assembler method can create and commit its own transaction. The batch of changes processes until the first error occurs. It is assumed that all changes that precede the error are applied to the data store. When these changes make it back to the client, their result handler is triggered. The change that caused the error is reported as a fault on the client. All changes that occur in the batch after the error are not sent to the assembler and are also reported as faults on the client.

Uniquely identifying data items

A Data Management Service destination contains one or more identity elements that you can use to designate data properties to be used to guarantee unique identity among items in a collection of objects. In the case of the SQL assembler, an identity element maps to a database field.

The boldface text in the following example shows an identity property:

...
    <destination id="contact">
        <properties>
...
        <metadata>
            <identity property="name"/>
        </metadata>
    </properties>
    </destination>
...

The identity element takes an optional type attribute, which is the Java class of the specified identity property. You must use this when your identity type may not have a one-to-one correspondence with ActionScript types. The most common problem is that an ActionScript Number is converted to either a long or an integer, depending on its value. The code in the following example shows an identity element with a type attribute:

<identity property="id" type="java.lang.Long">

A common mistake is to try to use one identity element for all properties, as the following example shows:

<metadata>
    <!-- Don't do this. -->
    <identity property="firstName,lastname"/>
</metadata>

Instead, you can specify multiple identity elements for a multiple field identity, as the following example shows:

<metadata>
    <identity property="firstName"/>
    <identity property="lastName"/>
</metadata>

The identity element can optionally take an undefined-value attribute, which you use to treat the identity of a property (usually of type int) as undefined. When an object is initially created on the client, often its identity is not known until the item is created on the server. In other situations, the client code defines the identity property value before the item is created by the Data Management Service. If null is not valid for a your data type, for example, if you have an int or Number as your identity property, you set the undefined-value attribute on the identity element to specify the undefined value. Often the number 0 (zero) is not a valid identity, so this would be the undefined value, as the following example shows:

<metadata> 
    <identity property="id" undefined-value="0"/>
</metadata>

If you do not specify an undefined value, the Data Management Service does not let you create two objects at the same time because both have the same identity value.

Using identity to manage relationships between objects

The Java adapter supports flat objects that only contain primitive fields and properties, as well as objects that have complex objects as properties. If you have complex objects as properties and those objects have their own identity property or properties, you can choose to define a separate destination to manage the synchronization of those instances based on the identity property or properties specified in an identity element in the destination definition. The following example shows a destination named contact that has a many-to-one relationship with a destination named account. The account destination has a complex property named contact and the contact destination manages each contact instance.

<!-- Child destination -->
<destination id="contact">
    <properties>
        <metadata>
            <identity property="contactId" undefined-value="0"/>
            <!-- Reference to acount destination that has a "contact" property -->
            <many-to-one property="account" destination="account" lazy="true"/>
        </metadata>...
</destination>

If there is no identity property for complex object properties and each instance is owned by its parent object, you can use the parent destination to manage the state of the object properties. For more information, see Hierarchical data.

Caching data items

By default, the Data Management Service caches items returned from fill() and getItem() calls and uses cached items to implement paging and to build object graphs on the server when implementing lazy associations. This causes a complete copy of the managed state of all active clients to be kept in each server's memory. You can turn off this caching of memory by setting cache-items to false, as the following example shows:

...
    <destination id="contact">
        <properties>
...
            <cache-items>false</cache-items>
...
    </properties>
    </destination>
...

If you set cache-items to false, you must specify a method to support paging or lazy associations in a get-method element when using this destination. When the cache-items property is false, the Data Management Service only caches the id values of the items on the server. This greatly reduces the footprint of data kept on the server, but there is still some memory used on the server for each managed object on each client. To eliminate this overhead entirely, you set DataService.autoSyncEnabled to false on the client, and either manually refresh clients or use the manual synchronization feature to route changes to clients. For information about manual synchronization, see Manually routing data messages.

Synchronizing data automatically

The auto-sync-enabled element controls the default value of the client-side DataService.autoSyncEnabled property for clients that are using a destination. The default value of this element is true.

The following example shows an auto-sync-enabled element:

...
    <destination id="contact">
        <properties>
...
            <auto-sync-enabled>false</auto-sync-enabled>
...
    </properties>
    </destination>
...

Using strong and anonymous types

The properties of a strongly typed object are defined at compile time by using declared fields or get and set methods. An anonymous type is usually represented in Java by a java.util.Map, and in ActionScript by an instance of type Object. For anonymous objects, type checking is performed at run time, not compile time.

You can use either strongly typed objects or anonymous objects with the Data Management Service on either the client or the server. For example, to use anonymous objects on both the client and server, your assembler returns java.util.Map instances that are converted to Object instances on the client. When the client modifies those Object instances, they are sent back to the assembler as java.util.Map instances.

To use strongly typed objects on the client and server, you define an ActionScript class that has explicit public properties for the data you want to manage with the [Managed] metadata tag. You map this class to a Java class on the server by using the [RemoteClass(alias="java-class-name")] metadata tag. Your Data Management Service destination in this case does not have to be configured with either class explicitly, which allows a single destination to support whatever instances your client sends to it. The client just has to expect the instances returned by the Java assembler, and the Java assembler has to recognize instances returned by the client. This allows one destination to support an entire class hierarchy of instances and you do not have to configure the Data Management Service destination explicitly for each class as long as they all have the same identity and association properties.

Using item-class to convert to anonymous ActionScript objects

The Data Management Service supports a technique that allows your Java assembler to return strongly typed Java instances that are converted to anonymous types on the client. In this case, you do not have to maintain ActionScript classes for each of your Java classes. When those anonymous instances are modified, the server receives them as java.util.Map instances. Data Management Service supports the item-class element in the properties section of a destination definition to automatically convert these instances back into a single strongly typed Java class that the Java assembler expects. Set the item-class element to refer to the Java class that your assembler expects. This pattern supports only the common case where each destination returns only instances of a single Java class. If your assembler must operate on a class hierarchy and you do not want to use strongly typed instances on the client, you must convert from the java.util.Map to your strongly typed instances in your assembler yourself.

You can also write a custom assembler that uses anonymous objects on the server that are serialized to strongly typed ActionScript classes on the client. To do this, you create an instance of the class flex.messaging.io.amf.ASObject that implements the java.util.Map interface. Set the type property of that instance to be the fully qualified class name of the ActionScript class that you want that instance to serialize to on the client, and store the property values that the ActionScript instance expects as key-value pairs in the java.util.Map. When that object is received by the client, the serialization code creates an instance of the proper type. Ensure that you declare an instance of the ActionScript class in your client-side code even if you are not going to use it. You must have a reference to the class to create a dependency on it so that it stays in the SWF file, as the following example shows:

public var myclass:MyClass;


 

Send me an e-mail when comments are added to this page | Comment Report

Current page: http://livedocs.adobe.com/livecycle/8.2/programLC/programmer/lcds/dms_config_5.html