The following options are available to control how the client loads association properties:
By default, the entire associated collection is sent to the client when the parent item is fetched. For general information about association properties, see Hierarchical data.
Loading only the identity properties
To avoid loading entire associated items when the parent object is loaded, the Data Management Service provides the lazy load option. With lazy loading, only the identity properties of the associated items are loaded with the parent object. The associated items are passed to the client by reference (identity property) instead of by value (entire object). When the client attempts to access an associated item for which it only has an identity property, an ItemPendingError is thrown. For information about ItemPendingErrors, see Item pending errors.
When using lazy loading, the assembler only returns the identity properties of the referenced objects. It does not have to fully populate these referenced objects. Lazy loading is enabled by setting the lazy attribute of an association element, such as a many-to-one, one-to-one, one-to-many, or many-to-many element, to true.
Not loading associated items until they are needed
When lazy loading is enabled, the assembler only has to fetch associated identity properties to satisfy a fill request. Although using lazy loading lets you avoid retrieving entire associated objects, it can still be inefficient for large association collections. To avoid loading an associated collection until it is needed on the client, the Data Management Service provides the load-on-demand option.
When you set the load-on-demand attribute to true on an association, the association property value is ignored from the initial getItem() and fill() methods. When the client first accesses the property, the getItem() method is called again for the parent item, and this time the property value is fetched. If load-on-demand is enabled and the lazy attribute is set to true for the association, when the associated property is first accessed only the identity properties of the items are fetched and the getItem() method is called on each identity property as that item is needed. If load-on-demand is enabled and the lazy attribute is set to false, the entire items are fetched when the association property is accessed.
For multi-valued association properties (for example, one-to-many and many-to-many properties), consider bringing in associated items or their identity properties one page at a time, instead of the entire associated collection once it is needed as load on demand lets you do. As with load-on-demand, the initial getItem() and fill() method calls do not return any of the association property values to the client. When the property is accessed on the client, the getItem() method is called again for the parent item. This time it must return a page of the associated collection. The length is returned to the client and the page containing the requested item is also returned.
To enable associated paging set the page-size attribute of an association element to the desired value. Like using load-on-demand, association paging is set independently of the lazy property. If the lazy property is set to true and either load-on-demand or paging is used, when the client attempts to access an item for which only the identity property is available, another ItemPendingError is thrown and the item is retrieved in its entirety by invoking the getItem() method.
The paged-updates Boolean attribute of an association property controls how changes are propagated between clients and the server. When the paged-updates attribute is set to false (default value), the entire collection is sent when the association value changes. When the paged-updates attribute is set to true, only the identity properties of the newly added or removed items are sent.
If the client uses paged updates to update a collection property, when those changes are committed to the server, the updateCollectionProperty() method on the Assembler interface is invoked to update the collection property.
When association values are paged (page-size value is set to a value greater than zero), paged updates are automatically enabled. However, enabling load-on-demand for associations does not automatically enable paged updates.
The PropertySpecifier object tells assembler operations, such as getItem(), fill(), and refreshItem() methods, which properties of a data item to populate. When a client discovers that it has the identity property of an item locally but not the entire item, it invokes a getItem() method on the server using the default property specifier. The default property specifier denotes that load-on-demand and paged association properties are not required to be populated on the item returned by the assembler for the getItem() call. As a result, you can code your custom assembler to skip such properties in its implementation of the getItem(Map identity, PropertySpecifier ps) method when ps is the default property specifier. Alternatively, your implementation of this method can invoke the Boolean PropertySpecifier.includeProperty() method with a specific property name to determine whether the property must be populated on this invocation of the getItem() method. You can use this method so that your assembler behavior is not hard-coded to know the settings of the load-on-demand and page-size properties that you use for a specific destination. For example, the implementation of the Hibernate assembler uses this variant to determine which properties must be fetched, and it reacts to the configuration changes that you make without requiring code changes to the assembler.
When the Flex client accesses a lazily loaded value for the first time, an ItemPendingError is thrown either from the ArrayCollection.getItem() method for multiple-valued associations or from the Managed.getProperty() method for single-valued associations. This causes a request to fetch the referenced object, and an event handler in the ItemPendingError is invoked to notify the client when the item is available. When you use Flex data binding, this behavior happens automatically when you set the lazy attribute to true; the data appears when it is needed. If you do not use data binding in conjunction with lazy loading, you can catch the ItemPendingError in your code and handle it accordingly.
An ItemPendingError is thrown when retrieving an item from an ArrayCollection requires an asynchronous call. When you bind a managed ArrayCollection to a List-based control other than a Tree control, itemPendingErrors are handled automatically when you have the paging element set to true on the destination. If the receiver of this error needs notification when the asynchronous call completes, it must use the addResponder() method and specify an object that supports the mx.rpc.IResponder interface to respond when the item is available. The mx.collections.ItemResponder class implements the IResponder interface and supports a data property.
In the following example, an ItemPendingError is thrown and caught when a group object is not yet available to a groupCollection object on the client. The groupCollection object is filled from the AssocGroup destination on the server. The destination has an admin property that is a lazily loaded reference to an AssocPerson instance. The printAdminName() method is called for the first group in the groupCollection object. If a group is not available, it throws an ItemPendingError. An ItemResponder is registered to handle the ItemPendingError; the ItemResponder calls the printAdminName() method when the group is available. If there is a fault, the ItemResponder calls the fetchAdminError() method.
...
import mx.collections.ItemResponder;
import mx.messaging.messages.ErrorMessage;
import mx.collections.errors.ItemPendingError;
...
public function printAdminName (data:Object, group:Object):void {
trace(group.admin.firstName);
}
public function fetchAdminError(message:ErrorMessage):void {
trace("error occurred fetching admin: " + message.faultString);
}
// This method is called to retrieve a "group" object
// that has a lazily loaded reference to a Person in its admin property.
// The printAdminName function may throw the ItemPendingError
// when it retrieves the group.admin property if that object has
// not yet been loaded by the client.
// The function registers a listener that calls printAdminName
// again when the value is available.
public function dumpAdminName():void {
try {
printAdminName(null, groupCollection.getItemAt(0));
}
catch (ipe:ItemPendingError) {
trace("item pending error fetching admin.");
ipe.addResponder(new ItemResponder(printAdminName, fetchAdminError,
groupCollection.getItemAt(0)));
}
}
...
The following configuration example shows a Hibernate destination with a one-to-many element that has the page-size attribute set to a nonzero value:
<destination id="account.hibernate">
<adapter ref="java-dao" />
<properties>
<use-transactions>true</use-transactions>
<source>flex.data.assemblers.HibernateAssembler</source>
<scope>application</scope>
<metadata>
<identity property="id"/>
<one-to-many property="accountContacts" destination="accountContact.hibernate"
read-only="true" pageSize="2" />
<many-to-one property="consultant" destination="consultant.hibernate"
lazy="true" />
</metadata>
<server>
<hibernate-config-file>support-hibernate.cfg.xml</hibernate-config-file>
<hibernate-entity>support.Account</hibernate-entity>
<fill-configuration>
<use-query-cache>false</use-query-cache>
<allow-hql-queries>true</allow-hql-queries>
</fill-configuration>
</server>
</properties>
</destination>
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_paging_4.html