EMF Containment behaviour
Whilst doing something with EMF (Eclipse Modelling Framework) recently I noticed some interesting behaviour when dealing with containment. I’ll describe it using two scenarios, each with an alternative.
Please note that full source for this article can be found here.
Scenario 1 : Order with bill and ship to addresses

Scenario 1 - Order with two composite aggregation associations to Address
The alternative involves loosening the composition down to a normal association for the bill to relationship:

Scenario 1a - Order with two associations to Address, only one being a composition
To get up and running with EMF I used annotated Java source to build the ecore and gen models. The Order has an order number with two associations to address. Both of these are marked as containment="true" to show that they’re whole-part relationships. The address has not associations, merely two attributes to store the property number and area code (e.g. zip or postal code).
public interface Order {
<…snip…>
/**
* @model containment=”true”
*/
Address getShipTo();
/**
* @model containment=”true”
*/
Address getBillTo();
}
From these, you should generate up the ecore and gen model using the standard EMF tooling and then use the genmodel to generate the EMF implementation for this model. N.B. I’m not going to go into detail about how I did that because there are other hello world style articles on the Eclipse and IBM websites.
To test the behaviour I created some very simple test scenarios to show what happens. My setup() for this scenario creates an order, two addresses and associates the two addresses with the order, as follows :
@Override
protected void setUp() throws Exception {
Scenario1Factory factory = Scenario1Factory.eINSTANCE;
orderFixture = factory.createOrder();
orderFixture.setOrderNum(ORDER_NUM);
// Create and assign a ship to address
shipToFixture = factory.createAddress();
shipToFixture.setPropNum(SHIPTO_PROPNUM);
shipToFixture.setAreaCode(SHIPTO_AREACODE);
orderFixture.setShipTo( shipToFixture );
// Now, create and assign a bill to address
billToFixture = factory.createAddress();
billToFixture.setPropNum(BILLTO_PROPNUM);
billToFixture.setAreaCode(BILLTO_AREACODE);
orderFixture.setBillTo( billToFixture );
}
Whilst I obviously have some fairly simple tests, the interesting test is this one :
public void testSetBillToAsShipTo() throws Exception {
Address shipTo = orderFixture.getShipTo();
orderFixture.setBillTo( shipTo );
// Double check the bill to
assertSame( shipTo, orderFixture.getBillTo() );
// Now check that the ship to is no longer set
assertNull( orderFixture.getShipTo() );
}
So this test get’s the order’s shipTo address and sets it as the order’s billTo address; we didn’t alter the shipTo in any way and yet it is now null. Why do we have this strange side effect? As you’ll see from the setup() it’s not just due to a wierd bug in setBillTo() automatically nulling the shipTo.
The crux of this relates to the containment (i.e. composition) of the relationships. This can be clearly demonstrated by moving to scenario 1a where the bill to association is no longer a composition. You can achieve this either by starting from new annotated java and not having containment="true" specified on the association, or (as I did) just alter the ecore model to change the containment property of the billTo association on Order and re-generate the model code.
Re-running the tests now results in this last case failing. To make the test pass now we have to replace the Null assertion with assertSame( shipTo, orderFixture.getShipTo() );.
Scenario 2 : Order with ship address and Invoice with ship to address

Scenario 2 - Order & Invoice with two composite aggregation associations to Address
The alternative involves loosening the Invoice’s billTo composition down to a normal association :

Scenario 2a - Order & Invoice with two associations to Address, only one being a composition
As you can see, this scenario is very similar to the first; the interesting test case now is :
Address shipTo = orderFixture.getShipTo();
invoiceFixture.setBillTo( shipTo );
// Double check the bill to
assertSame( shipTo, invoiceFixture.getBillTo() );
// Scenario 2 - Now check that the ship to is no longer set
assertNull( orderFixture.getShipTo() );
Again, the behaviour is consistent with the first scenario even though we’re dealing with two completely separate instances (i.e. the Order and the Invoice). So, is this right?
Well, in my opinion, absolutely it is. If you look at the persistence of the models (e.g. to XMI or XML) the containment semantics make this really obvious. The containment property is the mechanism that governs (certainly in XMI and XML) whether the instance should be serialized out as a child element. So that’s obvious from an EMF implementation perspective, that only one instance (the whole) can own the child instance (the part).
To help with the more abstract point of whether this is consistent with general composition semantics I turned to the UML 2.0 specification. Unfortunately, it wasn’t as clear as I’d like because, although it cleared up scenario 2, it leaves scenario 1 open. Section 7.3.3 Associations, Semantics states :
“Composite aggregation is a strong form of aggregation that requires a part instance be included in at most
one composite at a time.”
This clearly covers scenario 2, when we change ownership of the order’s shipTo address to the invoice it can no longer be associated to the order via it’s composition relationship. For scenario 1 it’s a little more murky and not absolutely nailed. The UML 2.0 Infrastructure spec defined composite as :
“A class that is related to one or more classes by a composition relationship. See: composition.“
and composition as
“A form of aggregation which requires that a part instance be included in at most one composite at a time, and that the composite object is responsible for the creation and destruction of the parts. Composition may be recursive.“
but it’s not as clear as I’d have liked and could be inferred to imply that it’s valid to have a part that is associated to the same instance via two composition associations at the same time.
I believe that composition is first and foremost an association related concept, not an instance or class concept (N.B. UML 2.0 Spec, section 7.3.3 is specifically about associations). Therefore, although in scenario 1, the Order instance has two associations to address, these are difference associations relating to different concepts and therefore the behaviour is valid. Another analogy would be a car; if I had a puncture and put the spare wheel on the front driver’s side; it’s no longer the spare wheel - it’s the same car, but the wheel cannot be two things at once.
One of the most pleasing things about all this though is that it all happens automatically in real time. When I first saw this behaviour it was during a test of the XMI serialised output and it was obvious that on reloading the XMI that my Order’s shipTo address would be null.
It’s great to see a framework manage to keep its internal state consistent even in these sort of conditions - now if only all frameworks were like that.