Pimcore: Pimcore | AbstractObject | Behaviour of hasChildren()

Created on 25 Feb 2020  路  4Comments  路  Source: pimcore/pimcore

Bug Report

In Pimcore 5 the following command returned false:

    $child = AbstractObject::getById(123); //fetch a data object
    $parent = $child->getParent();  //navigate to its parent
    $child->delete(); //delete the last child
    $parent->hasChildren(); //no more children -> false
````

However, in Pimcore 6.4.2. ``hasChildren`` will still return ``true`` if the last child is deleted, as the data object is obviously cached.

```php
$parent->hasChildren(); //returns true
AbstractObject::getById($parent->getId(), true)->hasChildren(); //returns false

What is the expected behavior? Would it make sense to adapt the code so that a child deletion will also affect the parent data object?

Bug

All 4 comments

Related to #5550

The only possibility to fix this would be to not cache any results regarding children at all, so to always query them from the database.

There are also other cases where this comes into play, e.g.:

$list = new DataObject\Listing;
$list->load();
$list->current()->delete(); 

foreach($list as $object) {
    // deleted object is still in list
}

or

$object = DataObject::getById(123);
$object->getChildren()[0]->delete();

foreach($object->getChildren() as $child) {
    // deleted object is still in list
}

This is also the case in Pimcore 5/4.

To be honest it is really difficult to weight which is the better way, also in relation to 99% of the other cases where performance is important.

@brusch Maybe implementing the "best" way and adding a section to the docs on how to deal with caching when deleting objects is the way to go? So we can utilize caching to the full extend, but it's also transparent for all developers how to deal with such use cases.

@brusch Thanks for your answer.
It is strange that in Pimcore 5 it appears to work, at least for my specific use case.

I agree with @jremmurd that it is probably only a matter of documentation.
What if we add a $object->refresh() method to make the behavior more transparent?

```php
public function refresh() {
return static::getById($this->getId(), true); //force reload of data object
}
````

@andreas-gruenwald @jremmurd we found at least an effective way how to fix the hasChildren() and getChildren() topic, so we're going to implement this soon.

@andreas-gruenwald the hasChildren() worked in Pimcore 5 but the getChildren() topic not, as far as I know :)

I also agree on the documentation topic, that would be indeed really helpful.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brusch picture brusch  路  3Comments

NiklasBr picture NiklasBr  路  4Comments

ghost picture ghost  路  4Comments

brusch picture brusch  路  5Comments

brusch picture brusch  路  5Comments