How to handle related null-objects correctly in sy

2019-09-11 10:05发布

问题:

The situation is that I have doctrine entity classes Category and Item with the following YAML definitions:

Category:
  columns:
    parent_category_id: { type: integer }
    name:               { type: string(255), notnull: true, notblank: true }
    items_count:        { type: integer, notnull: true, default: 0 }
  relations:
    ParentCategory: { class: Category, local: parent_category_id, foreign: id }

Item:
  columns:
    category_id: { type: integer, notnull: true }
    name:        { type: string(255), notnull: true, notblank: true }
  relations:
    Category: { local: category_id, foreign: id }

So, my categories can be structured in hierarchies. When creating a new item and assigning it to a category, items_count of that category and of all parent categories should be increased by one. For this, in the doctrine entity class Item, I override the member function save:

function save(Doctrine_Connection $conn = null)
{
  $is_new = $this->isNew();
  parent::save($conn);
  if ($is_new)
  {
    for ($category = $this->getCategory(); $category && $category->exists(); $category = $category->getParentCategory())
    {
      $category->registerNewItem($this);
      $category->save($conn);
    }
  }
}

Category::registerNewItem just increases items_count by 1.

My problem is that the auto-provided member function Category::getParentCategory returns a new dummy object (instead of returning null), if there is no parent category at all. I don't know how to handle these dummy objects correctly. The member function exists seems to work fine in the first place. But as soon as a category is saved more than once during the processing of a web request, saveGraph tries to save the dummy object as well, which is semantically wrong (at least in this case) and causes errors (e.g., the name has not been set, of course).

Now, my primary question is: What am I doing wrong? An alternative question could be: How to handle those dummy objects correclty? However, apart from that, I would like the auto-provided member functions get* and also findOneBy* to return null (instead of a newly created dummy object), if there is no such (related) entity at all.

Any hints are much appreciated.
Thanks in advance,
Flinsch