0

I have a self referencing entity in Doctrine but I keep getting the following error when I try to persist them:

PHP Catchable fatal error:  Object of class Category could not be converted to string in vendor/doctrine/dbal/lib/Doctrine/DBAL/Statement.php on line 165

Example:

$category1 = new Category();
$category1->setName("Foo");
$category1->setParent( NULL );

$category2 = new Category();
$category2->setName("Bar");
$category2->setParent( $category1 );

$manager->persist( $category1 );
$manager->persist( $category2 );

$manager->flush();

My entity looks like this:

/**
 * @ORM\Table(name="categories")
 * @ORM\Entity
 */
class Category {

    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=64, unique=true)
     */
    protected $name;

    /**
     * @ORM\Column(nullable=true)
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
     */
    protected $parent;

    /**
     * @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
     */
    protected $children;

    public function __construct()
    {
        $this->children = new ArrayCollection();
    }

    public function getId()
    {
        return $this->id;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setName( $name )
    {
        $this->name = $name;

        return $this;
    }

    public function getParent()
    {
        return $this->parent;
    }

    public function setParent( Category $parent = NULL )
    {
        $this->parent = $parent;

        return $this;
    }

    public function getChildren()
    {
        return $this->children;
    }

    public function setChildren( ArrayCollection $children )
    {
        $this->children = $children;

        return $this;
    }

}

I have Googled and compared my code to other examples but I can't seem to spot the problem. I'm obviously overlooking something, but what?

Luke
  • 20,878
  • 35
  • 119
  • 178

1 Answers1

3

Try to use

/**
 * @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
 * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", nullable=true)
 */
protected $parent;

But I also recommend you to set onDelete="SET NULL" on the parent column, like this:

/**
 * @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
 * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="SET NULL")
 */
public $parent;

I know it's not part of the question, but you are probably going to need this in the near future. If you want the children column to give you the categories in a order that the user can choose, you may want to add a integer column named order and define children like this:

/**
 * @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
 * @ORM\OrderBy({"order" = "ASC"})
 */
public $children;
Luke
  • 20,878
  • 35
  • 119
  • 178
rafaame
  • 822
  • 2
  • 12
  • 22
  • Give me +1 (up arrow on left of my answer) if this helped you. Thanks – rafaame Jan 28 '14 at 13:19
  • Thanks for that. This seems to work. Would you be able to explain *why* my version didn't work? Even though I had the syntax a bit different, I'd like to understand where the error came from. I'd up vote twice for the category suggestion if I could. :) – Luke Jan 28 '14 at 21:21
  • Hello. I think the only error was in the syntax (you putting nullable in a *column* annotation). – rafaame Jan 29 '14 at 10:16