3

I am currently implementing a web application in TYPO3 7/Extbase which has a complex object structure consisting of a root object and a tree of child objects.

Let's say it resembles a more complex version of:

Object A <--1:n--> Object B <--1:n--> Object C

Since instances of object a are aggregate roots I use an Object-A-Repository to persist the tree.

This worked well, for performance reasons I switched many of the relations to lazy loading though (making their object stoages lazy). This sped up the application immensely, but not all update() calls to the Object-A-Repository seem to work anymore. The problem occurs in cases where a method receives an object of type C, changes it and needs to persist the changes. C has parent links to his parent B, and B has a parent link to A (the lazy object storage's counterparts).

The problem seems to be related to the LazyObjectStorages not replacing themselves with the actual content (because the A object didn't use it's "side" of the relation in this case). If I call DebuggerUtility::var_dump() on the object before updating it, persistence works perfectly. If I don't, the database does not change.

Is there a way to force an object to load all it's lazy storages? Or should I go about solving this another way?

taalas
  • 395
  • 3
  • 16
  • Why would you need to persist a lazy storage? It should be definition not have changed and should not need any (new) persisting. – pgampe Jan 10 '17 at 00:10
  • Let's say I have a controller action that receives an instance of Object C, changes it and then persist the corresponding A instance (because it is this object's aggregate root). I have parent links to get to the A, but the A to B and B to C storages seem to be lazy still. – taalas Jan 10 '17 at 07:21
  • 1
    If you do something like `$A->getB->setC($C);` there should be not lazy object any more, because instances of lazy are replaced on access. – pgampe Jan 16 '17 at 15:00
  • Correct. The problem occurs if I receive an object of type C, change it, and then need to persist the changes. C has a link to B and B has a link to A (parent links), but in order to activate the lazy storage replacement I would have to backtrack to my C object. I will edit the question accordingly. – taalas Jan 26 '17 at 07:29
  • 2
    Not so clean, but if you need to change it independently, it might be more of an aggregated root anyway, just add the repository class for C and persist this one on its own. Relations are tracked by uid, thus there should not be any problems. – pgampe Jan 26 '17 at 21:38
  • Yes, that actually is what I came up with in the end as well. I persist the objects using an "in-between" repository. Thanks for your comments. – taalas Jan 27 '17 at 07:22

1 Answers1

0

If one action does only change Object C, why dont use a separat Repository for that model? You can very easily provide a repository in extbase.

I dont see any bad practice or problem in this case. By default typo3 will only persist the number of relations into the database field for objects_c, so you only need to persist changes via the aggregate root, if you add or remove objects. A simple update would work perfectly fine using a sub repository for ObjectC.

If you really need to do it via the aggregate root, you should make sure there is no LazyObjectStorage anymore.

By invoking one function of the concrete object, LazyObjectStorage will exchange its parents property (so the pointer to itself) with the real ObjectStorage.

For example

$objectA->getObjectsB()->current();

will set the property objectsB in $objectA as ObjectStorage (with all relations).

Other methods like $objectA->getObjectsB()->toArray() will work too of course.

Philipp Wrann
  • 1,751
  • 3
  • 19
  • 29