Throwing off some ideas. Have you thought about an entity A whose composed id is made of the id of two different entities B and C. A would enlist to B and C completion and would need to record when it receives the first event and process everything when the second event arrives?
A way around your problem could be to use index lookups instead of iterators to process the watch list. That way you can set a specific index to null when it is processed without affecting the subsequent indexes nor raise a CME. That would be close to a ring buffer implementation I suppose. Emmanuel On Tue 2014-09-02 13:41, Steve Ebersole wrote: > As part of the metamodel work, one of things I am working on is redesigning > the old notion of a "second pass" to be more efficient. For those not > familiar, this represents a piece of processing that needs to be delayed > until after another piece of processing is done. For example, processing a > composite identifier metadata for an entity might depend on the identifier > metadata for another entity being processed first. > > "second pass" was essentially one big bucket. In the new design I am > trying to categorize or segment these things better, so we have different > buckets (one for identifier metadata completion, one for attribute Type > metadata completion, etc). > > Not to get too involved, but essentially a bucket is a List of "watchers" > for specific "happenings" (I think of them as events, but am trying to > avoid that terminology for now). E.g., take the "identifier metadata > completion" bucket. As we complete the binding of the identifier metadata > for an entity, we fire off a notification of that happening. The watchers > can then react to that notification. > > The implementation of this is a List of watchers, as I said, which is > iterated over for each notification. So here comes the trickiness. As > each watcher is finished it needs to be removed from the list of watchers. > And a watcher could in turn kick off a new notification (for it completing > whatever it represents). So in the initial impl I ran into > ConcurrentModificationException problems. > > I went ahead and made it work just to move forward. But I wanted to circle > back and design this "right"; so I wanted to get others involved to see if > anyone had thoughts or better ideas. > > Here is a simple example to use as a basis for discussion: consider the > entity Customer and Order. Customer has a simple identifier, whereas Order > has a composite identifier made up of (1) FK to Customer and (2) a order > number. We need the identifier metadata for Customer to be completely > bound before we can process the identifier metadata for Order. That is the > crux of the problem to be solved. Its an ordering concern. If the > metadata for the Customer entity is processed first, no big deal. But of > course we can't really control that (putting the onus back on the user here > is fugly). So we need to account for the case where metadata for the Order > entity is processed first. This kind of timing thing is the reason for > second passes and these new notifications. The idea in the new design is > that we would register a watcher for Order which waits for the notification > that Customer identifier metadata has been finished. As the identifier for > each entity is completed, that process fires off a notification of that > fact. So as the identifier metadata for Customer is finished, the process > fires off a notification which makes its way back to the watcher for Order. > Processing can now bind the identifier metadata for Order, and in turn > fire off its notification. > > The trouble here, in the iteration impl, is that we are still iterating > over the "identifier metadata completion" notification, so there is an > active iterator over the list. When performing the Order-watcher > processing, since it no longer needs to watch, we would ideally remove it. > Initially I had simply exposed a deregistration method that removed the > watcher from the list, but that ran into the problems with CME. What I do > currently instead is to expose a method on the watcher contract for the > watcher to say whether its work is done, and if so use the Iterator to > remove it. That works, just not sure its the best option. > > Another consideration is the iteration over non-interested watchers. This > may be a non-issue, not sure yet. Currently watchers simply register as > being interested in identifier metadata completion notifications, not > notifications for completion of identifier metadata for specific entity(s). > So on the con side, the List would become a Map and we'd need a key > object. On the plus side we'd avoid the iteration and CME problems > altogether. > _______________________________________________ > hibernate-dev mailing list > hibernate-dev@lists.jboss.org > https://lists.jboss.org/mailman/listinfo/hibernate-dev _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev