Hi Greg,

 

We're working hard on this type of problem to make this type of thing
more robust.   One of the tricky problems you are hitting here is a weak
spot in our implementation right now.  

 

When you remove an item from a managed collection, and there are no
other explicit references to that item it gets "released" by the system.
At that point, it no longer is listening for changes.   Since we don't
yet have cascade="delete" in the LCDS model, removing an item doesn't
automatically delete it and once it has been removed, it can be awkward
to do so if it gets released like this.   We should keep track of that
item and maybe release it at the end of the frame still tracking changes
to it in the meantime.   Technically you can call getItem to add a
reference but that will always go back to the server now so it is not a
simple workaround.  

 

 I'll drop you an email directly on resolving some of the other issues
you are seeing - sounds like something else is getting messed up when
you hit this situation (feel free to contact me offllist if there is a
different email I should use).  

 

The simplest way to remove items from the collection is to just call
deleteItem using the data service for that type of item.  Since you got
that item through an association you may not have a data service but
just call new DataService("Slide").deleteItem(slides.getItemAt(i)).
For example, you might delete a list of account contacts like this...
the loop is written from back to front since each deleteItem call will
remove the last entry and reduce the length

 

                for (i = accountContacts.length-1; i >= 0; i--)

 
contactsService.deleteItem(AccountContact(accountContacts.getItemAt(i)))
;

 

BTW, 2.6 (now in a private beta) has more complete support for sub-types
-one destination can extend another destination and you can use
polymorphic associations and add/remove association properties in
sub-types.  The hibernate support in 2.6 auto-generates the metadata
settings and any destinations for any associated types automatically
from the hibernate configuration.    There are two new association
attributes you can set: load-on-demand="true" and page-size=".." which
make it much more efficient to load large collections.   We also support
hibernate annotations so there is some nice new stuff in 2.6.  This will
all be in a public beta available real soon now.  

 

Jeff

 

________________________________

From: flexcoders@yahoogroups.com [mailto:[EMAIL PROTECTED] On
Behalf Of gordon_greg
Sent: Tuesday, April 01, 2008 12:02 PM
To: flexcoders@yahoogroups.com
Subject: [flexcoders] Flex DataService problem: unexpected "unsubscribe"
and "release collection" ops

 

Hello,

I have a small, yet increasingly, complex application begun using Flex
DataServics / Tomcat / Spring / Hibernate, and am running into what
apparently are not uncommon limitations with regards to the complexity
of the data model when using DataServices.

The skinny: when deleting an item from a managed collection, instead of
the client issuing the correct 'update' operation on the collection,
some internal Adobe code detects something that results in the entire
collection being released, the consumer being unsubscribed, and the
destination being disconnected...

By and large things work well, but I recently added in some inheritance
to a particular table that may or may not be causing me trouble.

Before getting overly detailed as to my exact data model, let's try the
following summary:

1) table "Presentation" has a collection of "slides"

2) table "Slide" is extended by table "SlideMaster" and "SlideRefe!
rence", joined on a shared primary key

3) table "SlideMaster" has a collection of "slideElements", and
"slideReferences"

4) table "SlideReference" simply points back to a parent "slideMaster" 

For my destination configuration, I actually define a destination for
each table: spring.presentation, spring.slide, spring.slideMaster,
spring.slideReference, etc.

Note: all DataServices are set to autoCommit = false, and autoSync =
true.

Note that this is not actually the top of my object tree, but let's just
deal with the notion of adding and removing Slides from a Presentation.

I can properly add slides by:

        mySlide = new SlideMaster();
        mySlide.presentation = myPresentation;
        myPresentation.slides.addItem(mySlide);
        // then do a commit

This works fine.
However, when I attempt to remove a slide:

index = myPresentation.slides.getElementIndex(mySlide);
myPresentation.removeItemAt(index);   

What happens is very odd and very frustrating.  

I have ALL of the debug logging enabled, so the first thing I see is a
message queued to destination spring.presentation, operation = update.
This is as expected.

Next, I see the propertyChangedEvent handlers called on my DataServices,
indicating that commitRequired has gone from false to true, again as
expected.

However - when not stepping through breakpoints, etc., the next thing
that happens is a subsequent call to the properyChangedEvent handlers,
indicating that commitRequired is now FALSE, and this is followed by the
client issuing the following log messages:
-------------------- logging start -------------------
4/1/2008 14:37:32.233 [INFO] mx.messaging.Consumer 'cds-cons!
umer-spring.slide-null' consumer unsubscribe.
4/1/2008 14:37:32.235 [WARN] mx.messaging.Consumer
'cds-consumer-spring.slide-null' consumer channel disconnected.
4/1/2008 14:37:32.236 [INFO] mx.messaging.Producer
'ds-producer-spring.library' producer sending message
'296B7FA3-B4AB-2F9E-5FE8-0B479ACC829B'
4/1/2008 14:37:32.238 [DEBUG] mx.messaging.Channel 'my-amf' channel
sending message:
   
   [... operation = release; destination = spring.slide ...]

4/1/2008 14:37:32.240 [INFO] mx.messaging.Consumer
'cds-consumer-spring.presentation-null' consumer unsubscribe.
4/1/2008 14:37:32.240 [WARN] mx.messaging.Consumer
'cds-consumer-spring.presentation-null' consumer channel disconnected.
4/1/2008 14:37:32.240 [INFO] mx.messaging.Producer
'ds-producer-spring.library' producer sending message
'ADABC35E-C24F-283B-46DC-0B479AD08F51'
4/1! /2008 14:37:32.242 [DEBUG] mx.messaging.Channel 'my-amf' ! channel
sending message:
  
   [... operation = release; destination = spring.presentation ...]
-------------------- logging end -------------------

Basically, when I remove mySlide from the myPresentation.slides
collection, after DataServices queues up the correct udpate message and
sets commitRequired to true, something else happens way beneath the
covers that results in this errant cancellation of the update, and
subsequent release of the collections.

I attempted to dig deeper by stopping execution at the point at which
the second call was made to the propertyChangedEvent handler, and found
the reason for this behavior has something to do with some internal
Adobe classes, and seems most specifically due to something called
releaseItemIfNoDataListReferences, which seems to get something
confused... either as though the entire myPresentation.slides collection
should be released, or... or what, I'm not sure, but it is at this
point, if I step through the code (without of! course being able to see
the code, since I don't have the source) that things change and those
releases occur.

Here is the stack at the point at which my PropertyChange handler is
notified that commitRequired is now false:

com.nv.client.model::PresentationsProxy/handlePropertyChange    
flash.events::EventDispatcher/dispatchEventFunction [no source]    
flash.events::EventDispatcher/dispatchEvent [no source]    
flash.events::EventDispatcher/dispatchEventFunction [no source]    
flash.events::EventDispatcher/dispatchEvent [no source]    
flash.events::EventDispatcher/dispatchEventFunction [no source]    
flash.events::EventDispatche! r/d ispatchEvent [no source]    
mx.data::DataMessageCache/checkCommitRequired    
mx.data::DataMessageCache/removeMessage    
mx.data::ConcreteDataService/internalReleaseItem    
mx.data::ConcreteDataService/http://www.adobe.com/2006/flex/mx/internal:
:releaseDataList    
mx.data::ConcreteDataService/http://www.adobe.com/2006/flex/mx/internal:
:releaseAssociations    
mx.data::ConcreteDataService/http://www.adobe.com/2006/flex/mx/internal:
:releaseItemIfNoDataListReferences    
mx.data::DataList/removeItemAt    
mx.collections::ListCollectionView/removeItemAt    
com.nv.client.model::PresentationsProxy/removeSlide    
com.nv.client.mediators.views::PresentationMapMediator/deleteSlideHandle
r    
flash.events::EventDispatcher/dispatchEventFunction [no source]    
flash.events::EventDispatcher/dispatchEvent [no source]    
mx.core::UIComponent/dispatchEvent    
com.nv.client.view.presentations::PresentationTableSlideCell/deleteSlide

com.nv.client.view.presentations::PresentationTableSlideCell/menuHandler

flash.events::EventDispatcher/dis patchEventFunction [no source]    
flash.events::EventDispatcher/dispatchEvent [no source]    
mx.core::UIComponent/dispatchEvent    
mx.controls::Menu/dispatchEvent    
mx.controls::Menu/mouseUpHandler    

I was able to work around this, somewhat, by doing the following:

index = myPresentation.slides.getElementIndex(mySlide);
mySlide.presentation = null;  // note this is not allowed in the DB
myPresentation.removeItemAt(index);   
mySlide.presentation = myPresentation; 
// do commit

This seems si! lly, of course, but if I remove the reference to the
parent Presentation from the Slide before removing it, then those nasty
unsubscribe/release collection operations are not triggered, and the
slide is deleted successfully.

However - IF I first delete a slide, and then attempt to add a slide, I
run into a new problem, in that the client for some reason injects the
primary key value of the DELETED slide into the upbound "create"
opeartion for the NEW slide.

So - if I delete slide with id=28, then create a new slide, the first
thing I see is a queued message for a new slide with id=0, as expected,
and I then see a message queued to update the presentation.slides
collection. However, when I commit, I see the actual message sent to the
server has changed from the queued message, and instead of id=0 for the
new slide, I now see id=28.

I am totally perplexed by this, and of course I suppose it's possible
that my inhertance scheme is confusing somet! hing somewhere, and I'd
hate to think that after investing the! last mo nth of my time getting
past various other idiosyncrasies of Flex LCDS, that I'd have to
rewrite everything using RemoteObjects or some other solution.

Any information would be greatly appreciated, and I am happy to provide
many more gory details as necessary.

Thanks in advance!

Greg

 

Reply via email to