8 Replies Latest reply on Mar 5, 2009 8:08 AM by mitchgrrt

    debugging an LCDS problem

    mitchgrrt Level 1
      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. Re: debugging an LCDS problem
          jeffvroom
          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.
          • 2. Re: debugging an LCDS problem
            mitchgrrt Level 1
            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.
            • 3. Re: debugging an LCDS problem
              jeffvroom 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.
              • 4. Re: debugging an LCDS problem
                mitchgrrt Level 1
                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.
                • 5. Re: debugging an LCDS problem
                  jeffvroom 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.
                  • 6. Re: debugging an LCDS problem
                    mitchgrrt Level 1
                    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?

                    • 7. Re: debugging an LCDS problem
                      jeffvroom 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.
                      • 8. Re: debugging an LCDS problem
                        mitchgrrt Level 1
                        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;
                        }