Wednesday, October 18, 2006

Passing Objects on a dataservice fill()

A couple of weeks ago I ran into an interesting issue regarding the passing of a value object as one of the elements in my FillParameters array. Something like this:

dataservice.fill(employees, CompanyVO)
The fill worked fine everytime, however, if I went and added a new employee using:
dataservice.createItem(employee);dataservice.commit();
the collection on my client would not update to show the new employee. Sure I could add the employee by doing an employees.add(employee), and yes, my collection would be updated. However, another employees collection on another client viewing the same records would not.

I turned up the logging level to debug and watched how Flex Data Services was handling the request. It seemed, after a bit of extensive testing, that it did not recognize the CompanyVO object as being the same one across multiple calls. The debugger would even state that no client collections existed with this fill configuration, and therefore none would receive a refresh.

I thought perhaps my CompanyVO.as was perhaps not mapping thru to my CompanyVO.class, so I put my own toString() method in with a quick little output line. Sure enough, FDS was recognizing the object passed as a CompanyVO.class object.

Eventually I gave up. I had played with my java class, trying to override various methods, implementing icomparable, etc. Nothing.

Then Jeff Vroom posted a suggestion on flexcoders. To override the (built-in) in uid property on the Object. First I added some code to have uid equal the companyid, saved my flex project and ran it again:
Company.as
public var uid:String = "";
...
company.uid = company.companyid;

No luck. Then I added the uid property to my java class as well:
private String uid;
public void setUid(String uid)
{ this.uid = uid;}
public String getUid()
{ return this.uid;}

Restarted FDS and ran my flex project again. Problem solved. Here's the steps to reproduce this problem using the crm sample that comes with FDS(as posted by me in the Adobe FDS Forum):

1) in companyapp.mxml, change the fill line in the companyChange function to read:
dsEmployee.fill(employees, company) //change from companyId int to company VO

2) in the crm sample application, addEmployee function, replace this line:
employees.addItem(employee);
with this:
dsEmployee.createItem(employee);
(you don't have to do this if you keep 2 instances of the app running)

3) in the crm.samples.EmployeeAssembler fill method, change the fill by commenting out everything after the line that says return dao.GetEmployees(); and replace them with these lines:
Company cp = (Company) fillParameters.get(0);
return dao.findEmployeesByCompany(cp.getCompanyId());

4) in the crm.samples.EmployeeAssembler createItem method, replace the second dtx.refreshFill with the following line:
dtx.refreshFill("crm.employee", Arrays.asList( new Object[] {newEmployee.getCompany()}));

2 comments:

Matt Chotin said...

Hi Vic, I hadn't seen this blog before and it looks like you have good information. Have you added yourself to the MXNA aggregator? http://weblogs.macromedia.com/mxna. Go there and click Submit Feed at the top. It'd be good to see a blog that has a focus on data services and other relevant topics.

Anonymous said...

Prompt reply)))