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