Using large datasets with CF8 and LCDS

When ColdFusion 7 introduced support for LifeCycle Data Services (FDS at that time), we were forced to use CFCs. Due to CFC's creation overhead, it was a painful job for CFers when dealing with large datasets (+1000 records).

With CF8, CFC creation has improved a lot in this area. First of all, CFC creation is a lot faster, for an array of 1000+ CFCs, with 8 properties + 1 lazy loaded object we registered with trusted cache on, an average time of 4.5 seconds in CF7. With CF8 we are around 1 sec for the exact same collection.

This indeed is a big difference but the CF team didn't stop there.

CF8 introduced new ways of returning those arrays to the flex client. I'll use Tom Jordahl's CRM sample as a reference.

We will have to modify the data-management-config.xml (where all data management destinations are defined). It can be found under the {cfusion.war}/WEB-INF/flex folder for CF8 Multi-server (or Coldfusion8/wwwroot/WEB-INF/flex folder).

The first option, is to use the THIS scope and ignore the getters and setters in the Value Objects. You do this by adding in your destination under the properties node.

<destination id="cfcompany">
<properties>
...
...
<use-accessors>false</use-accessors>
</properties>
</destination>

By enabling this you can now replace in your generated DAO files, all calls made to getters/setters by myCFC.PropX.

Using Getters & Setters

<cfscript>
obj = createObject("component","samples.crm.Company").init();
obj.setcompanyId(qRead.companyId);
obj.setname(qRead.name);
obj.setaddress(qRead.address);
obj.setcity(qRead.city);
obj.setzip(qRead.zip);
obj.setstate(qRead.state);   
obj.setindustry(qRead.industry);
ArrayAppend(ret, obj);
</cfscript>

Using THIS scope:

<cfscript>
obj = createObject("component","samples.crm.Company").init();   
obj.companyId=qRead.companyId;
obj.name=qRead.name;
obj.address=qRead.address;
obj.city=qRead.city;
obj.zip=qRead.zip;
obj.state=qRead.state;   
obj.industry=qRead.industry;
ArrayAppend(ret, obj);
</cfscript>

You can also clean up your Value Objects and remove all getters & setters. Once again, the time to create the same array will be smaller.

The second option is to use structures instead of CFCs. To do that, you just need to change your DAO code, no configuration change is needed.

<cfscript>
obj = structnew();   
obj['__type__'] = 'samples.crm.company';
obj['companyId']=qRead.companyId;
obj['name']=qRead.name;
obj['address']=qRead.address;
obj['city']=qRead.city;
obj['zip']=qRead.zip;
obj['state']=qRead.state;   
obj['industry']=qRead.industry;
ArrayAppend(ret, obj);
</cfscript>

Two important things: first is the fact that we don't use struct.variable, otherwise we would get all variables in uppercase in the flex side. Use struct['variableName'] to keep the right case, and second is the additional variable __type__ which is used by the assembler, while converting those structures to ASObjects. So what kind of CFC should they represent? The value is the same as the one used in the alias attribute in your CFC.

The third option is to return queries directly to the flex client. For that, you need to change your destination configuration and add a query-row-type attribute like this

<metadata>
<identity property="companyId" />
<query-row-type>samples.crm.company</query-row-type>
</metadata>

The query-row-type will have the same function like the __type__ variable when using structures.

This solution is only valid when not working with related objects.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
BlogCFC was created by Raymond Camden. This blog is running version 5.8.001. Design by dcarter.