Weird call sequence on EStore with containment reference [message #998725] |
Thu, 10 January 2013 15:06 |
Andreas Voss Messages: 1 Registered: July 2009 |
Junior Member |
|
|
I'm implementing an EStore to encapsulate our legacy database.
In my test scenario I have the classes "Customer" and "Account" and a 0..* containment reference "accounts", so a customer may own many accounts. When I call
customer1.getAccounts().add(account1);
EMF first performs some checks and then calls
1. myStore.add(customer1, reference, index, account1);
which is fine. myStore persists account1 and remembers its new container, customer1. Then EMF asks myStore for the container of account1:
2. myStore.getContainer(account1)
and myStore returns "customer1" which was just passed to myStore.add(). Then EMF decides to remove account1 from its container and calls:
3. myStore.remove(customer1, reference, index)
It looks like DelegatingNotifyingListImpl.addUnique() first calls addUnique() and then inverseAdd() which in turn calls eBasicRemoveFromContainer().
I would understand if EMF did something like:
oldContainer = store.getContainer(object);
if (oldContainer != null)
removeFromContainer(oldContainer, object);
store.add(newContainer, object);
but it looks like:
store.add(newContainer, object);
oldContainer = store.getContainer(object);
if (oldContainer != null)
removeFromContainer(oldContainer, object);
Any ideas what went wrong?
Thanks in advance,
Andreas
|
|
|
Re: Weird call sequence on EStore with containment reference [message #998786 is a reply to message #998725] |
Thu, 10 January 2013 17:43 |
Ed Merks Messages: 33216 Registered: July 2009 |
Senior Member |
|
|
Andreas,
Comments below.
On 10/01/2013 4:08 PM, Andreas Voss wrote:
> I'm implementing an EStore to encapsulate our legacy database.
>
> In my test scenario I have the classes "Customer" and "Account" and a
> 0..* containment reference "accounts", so a customer may own many
> accounts. When I call
>
> customer1.getAccounts().add(account1);
>
> EMF first performs some checks and then calls
>
> 1. myStore.add(customer1, reference, index, account1);
>
> which is fine. myStore persists account1 and remembers its new
> container, customer1. Then EMF asks myStore for the container of
> account1:
>
> 2. myStore.getContainer(account1)
>
> and myStore returns "customer1" which was just passed to myStore.add().
Do you have
org.eclipse.emf.ecore.InternalEObject.EStore.getContainingFeature(InternalEObject)
properly implemented?
> Then EMF decides to remove account1 from its container and calls:
>
> 3. myStore.remove(customer1, reference, index)
>
> It looks like DelegatingNotifyingListImpl.addUnique() first calls
> addUnique() and then inverseAdd() which in turn calls
> eBasicRemoveFromContainer().
> I would understand if EMF did something like:
>
> oldContainer = store.getContainer(object);
> if (oldContainer != null)
> removeFromContainer(oldContainer, object);
> store.add(newContainer, object);
>
> but it looks like:
>
> store.add(newContainer, object);
> oldContainer = store.getContainer(object);
> if (oldContainer != null)
> removeFromContainer(oldContainer, object);
Where does it look like this?
It's more like you add an x to a y, and then it tells the x (the other
end of the bidirectional reference) that it it should add y, and then x
knows (in this case) that it's a container reference, which is mutually
exclusive with any other containment reference, so it knows to remove x
from its current container before adding (setting actually) y...
I know Eike said this was really hard to implement this in CDO...
Probably it will be helpful to trace the same logic in a non-store
model. Perhaps it will be helpful to look at the CDO implementation...
>
> Any ideas what went wrong?
> Thanks in advance,
> Andreas
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Powered by
FUDForum. Page generated in 0.02963 seconds