[DC-515] HYDRATE_RECORD_HIERARCHY broken with many roots Created: 22/Feb/10  Updated: 09/Jun/10

Status: Reopened
Project: Doctrine 1
Component/s: Nested Set
Affects Version/s: 1.2.0
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Kamil Rojewski Assignee: Guilherme Blanco
Resolution: Unresolved Votes: 0
Labels: None


 Description   

DB schema:

Category:
actAs:
NestedSet:
hasManyRoots: true
rootColumnName: root_id
columns:
id:
type: integer(4)
primary: true
autoincrement: true
name:
type: string(64)
notnull: true
image: string(64)
indexes:
tree:
fields: [lft, rgt, root_id]

Sample data:

id: '1'
name: 'Przykładowa kategoria 1'
image: null
root_id: '1'
lft: '1'
rgt: '6'
level: '0'

  • id: '2'
    name: 'Przykładowa kategoria 2'
    image: null
    root_id: '2'
    lft: '1'
    rgt: '6'
    level: '0'
    -
    id: '3'
    name: 'Przykładowa podkategoria 1'
    image: null
    root_id: '2'
    lft: '2'
    rgt: '5'
    level: '1'
    -
    id: '4'
    name: 'Przykładowa podkategoria 2'
    image: null
    root_id: '2'
    lft: '3'
    rgt: '4'
    level: '2'
    -
    id: '5'
    name: teset1
    image: null
    root_id: '1'
    lft: '2'
    rgt: '5'
    level: '1'
    -
    id: '6'
    name: test2
    image: null
    root_id: '1'
    lft: '3'
    rgt: '4'
    level: '2'

When using HYDRATE_RECORD_HIERARCHY, the first top-level category is empty. Everything is assigned to the other one. Only single-root trees work properly.



 Comments   
Comment by Kamil Rojewski [ 17/Mar/10 ]

If you look at Doctrine_Collection::toHierarchy() you'll notice that there is NO reference to root_id, therefore it treats the entire collection as 1 tree (which is false). The bug is 100% repeatable. I've made a fast walkaround ba adding a multi-tree hydrator:

class MultiRootHydrator extends Doctrine_Hydrator_RecordDriver
{
  public function hydrateResultSet($stmt)
  {
    $result = parent::hydrateResultSet($stmt);

    $collection = array();
    foreach ($result as $item)
    {
      if (!isset($collection[$item->root_id]))
        $collection[$item->root_id] = new Doctrine_Collection($result->getTable());

      $collection[$item->root_id]->add($item);
    }

    $result = new Doctrine_Collection($result->getTable());
    foreach ($collection as $tree)
    {
      $tree = $tree->toHierarchy();
      $record = $tree->getFirst();

      $result->add($record, $record->root_id);
    }

    return $result;
  }
}

It should clarify the problem.

Comment by Jonathan H. Wage [ 08/Jun/10 ]

I think it was intended that you would only convert a single tree to a hierarchy. What would the structure of the returned data be like?

Comment by Kamil Rojewski [ 09/Jun/10 ]

A Doctrine_Collection with root nodes seems to work fine. It allows to traverse the tree for each root.

Generated at Wed Apr 23 17:50:18 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.