Attempt to update lazy loaded object will not persist this object when persisted through the aggregate root's repository

There is an aggregate with classes Foo (aggregate root) and Bar.

Foo [1] <>---------- [0..*] Bar

You can edit a Bar via the Bar-edit-form - the modified Bar should be persisted via the aggregate root’s repository FooRepository:

/**
 * @param Bar $bar
 * @return void
 */
public function updateBarAction(Bar $bar) {
	$foo = $bar->getFoo();
	
	// Workaround to retrieve lazy loaded Bars - otherwise updating
	// Foo would not include the edited/modified Bar: the original
	// Bar would still be associated with the Foo.
	$foo->getBars()->toArray();
	
	$this->fooRepository->update($foo);
}

Debugging reveals that without using toArray() or similar methods the bar attribute of Foo will be an empty Doctrine\ORM\PersistentCollection throughout the whole updateBarAction().

I guess this has something to do with lazy loading - configuring Foo.bars to be eager loaded also solves the described problem - but I do no want to load this attribute eagerly.

Am I missing something? Is this a bug/missing feature in Doctrine/Flow? How would you work around it? What do you think about my workaround?

Please also have a look at the attached screenshots without-workaround.png and with-workaround.png.

I am using Flow 3.0.0-beta3.

without-workaround.png

with-workaround.png

I agree this is a problem but I am not sure this can/should be solved. It needs to be clearly documented.

From a technical point of view IMHO you shouldn’t even be editing the “bar” separately from it’s aggregate root. If you would access it through the “foo” you wouldn’t have that problem obviously. I think the workaround is fine if doing that is your usecase.

2 Likes

Interesting. I will have to think about that and if this is doable in our case.