Expand my Community achievements bar.

SOLVED

debugging an LCDS problem

Avatar

Level 2
We have an application that's doing this (greatly simplified)



var list:ArrayCollection; // list of PositionVO

service.fill(list);

var temp:PositionVO;

temp.title = "hello";



The list is a list of PositionVO objects and it is filled by
an LCDS DataService. We
think the temp object is not part of the list and should not
be managed by LCDS.



However, the assignment of temp.title makes the property
service.commitRequired change value from false to true. This makes
us think that something has gotten messed up, either in our program
logic or inside LCDS, to make LCDS think that it is managing the
temp object. Soon after other things start going wrong with LCDS.
To figure out why, we are focused on trying to find out why the
assignment to temp.title changes the value of
service.commitRequired.



Is there some way of debugging this? I was looking around for
an API call that would let us ask LCDS whether it thinks it is
managing the temp object, but I didn't find anything.
1 Accepted Solution

Avatar

Correct answer by
Level 1
Geez, not my day. Apparently the managed code gen does this:



private var _115792uid:String;

[Transient]

[Bindable(event="propertyChange")]

public function get uid():String

{

if (_115792uid == null)

{

_115792uid = mx.utils.UIDUtil.createUID();

}

return _115792uid;

}



so it will get set to a UUID as soon as you try to get it if
you use the getter. We will always set it before getting it though
so we'd (hopefully!) avoid that extra UID. If you can find that
_xxxuid member variable you could look at that and it would be more
reliable.



One trick that might work is to put your own public uid
get/set methods into PosititionVO. You can then set a breakpoint in
the "set" method. We'll call that from where it becomes managed.
You can then go up in the stack in the debugger till you find where
in your code you are doing that assignment.

View solution in original post

8 Replies

Avatar

Level 1
LCDS should only be listening for events for the managed
instances. There are a few ways you can check. there is a
"getLocalItem" method which can retrieve the managed instance for a
particular id. Inside of the item itself, there is a
mx_internal::uid property which gets set for "the" managed object.
The <mx:TraceTarget/> is also pretty useful for seeing what
has happened in the system up until that point.



In general, a newly created PositionVO would not be managed
by anything you get out of or put into that "list" array collection
would be managed.

Avatar

Level 2
Is there an example of how to call getLocalItem()? From
reading the doc I'm not getting it, and Google is not helping.
Calls I have tried have thrown exceptions. Thanks.

Avatar

Level 1
Here's the ASDOC:



/**

* Looks up the supplied item with the given identity. If the
item is already

* managed on this client, the managed instance is returned.
If not, null is

* returned. Unlike the getItem call, this call does not make
a request to the

* server and does not add an additional reference to the
item.

*

* @param An Object that contains the identity properties for
the desired object.

* @return The managed object or null if the item with this
id is not yet managed

* on this client.

*



Basically you'd call it like:



var myItem:Object = dataManager.getLocalItem({id:1234})



Really though, you could pass in any object which has the
identity properties including the VO itself.

Avatar

Level 2
In my case the temp object hasn't yet been saved to the
server. It has an id field but the value of the field is 0.



getLocalItem(temp) throws a DataServiceError exception with
the message "null identity passed into getLocalItem".



This makes it appear that temp is NOT being managed. However,
the behavior I mentioned in the first message in this thread is
still true. Assigning temp.title = "hello"; causes
service.commitRequired to change from false to true, making us
think that temp IS being managed. So this is still
confusing.

Avatar

Level 1
Oh, I should have mentioned that method does not work for
"newly created" items. You have to have an id assigned to look it
up by id. For newly created items, in the debugger if you show all
variables (including those not accessible in the current context)
you should see the variabled called "uid" in your managed instance.
That gets assigned when the object is managed. for a newly created
object, it will be a "UUID" - i.e. a string with lots of hex
digits. That corresponds to the messageId of the "create" message
we'll use to persist that object in the server. If you enable
<mx:TraceTarget/> you should see a message getting queued
when we log the create message for that new object. If you are not
calling "createItem" explicitly, or adding that instance to a
managed collection, it might also get created if another managed
object has a property assigned to this managed reference.

Avatar

Level 2
I see that temp.uid is this value:



uid = "64DCDBBA-A0A7-7FA6-39B5-D385AF574CF1"



Does that mean temp is managed by LCDS? It has this value
right after a call to temp = new PositionVO();



Backing up a little, I think that at the time temp is newed,
it is not being managed by LCDS, but then later it is becoming
managed because it has gotten referenced by some other managed
object. I'm trying to find a way to debug this and figure out at
what point in the code temp is becoming managed, or what other
managed object is referencing it. Is there a way at any given point
in time to ask LCDS whether it is managing temp?



Avatar

Correct answer by
Level 1
Geez, not my day. Apparently the managed code gen does this:



private var _115792uid:String;

[Transient]

[Bindable(event="propertyChange")]

public function get uid():String

{

if (_115792uid == null)

{

_115792uid = mx.utils.UIDUtil.createUID();

}

return _115792uid;

}



so it will get set to a UUID as soon as you try to get it if
you use the getter. We will always set it before getting it though
so we'd (hopefully!) avoid that extra UID. If you can find that
_xxxuid member variable you could look at that and it would be more
reliable.



One trick that might work is to put your own public uid
get/set methods into PosititionVO. You can then set a breakpoint in
the "set" method. We'll call that from where it becomes managed.
You can then go up in the stack in the debugger till you find where
in your code you are doing that assignment.

Avatar

Level 2
That gave us enough info to find the problem.it. Thanks for
the help.



For future reference, here's the override I did. After doing
this you can set a debugger watchpoint on someObj.managedByLCDS to
see what's going on.



[Transient] private var managedByLCDS:Boolean = false;



[Transient]

[Bindable(event="propertyChange")]

public override function set uid(id:String):void

{

managedByLCDS = true;

super.uid = id;

}



public override function get uid():String

{

return super.uid;

}