Jeebs24
Jeebs24

Reputation: 177

How do I save associated entities in Doctrine 2?

After a few hours of searching for an answer I have to ask this in StackOverflow. This seems such a basic thing to do but I'm still quite new to Doctrine2 so forgive me if the answer is simple or if I'm totally looking at Doctrine incorrectly.

My problem is that my foreign keys are not being populated. I was assuming Doctrine would do it automatically.

For example, I have two entities: Name and EmailAddress with a OneToMany relationship. Name has many EmailAddress and EmailAddress has one Name.

Here's pre-populated tables.

Table: name       Table: email_address

| id | name |     | id | email_address     | name_id |
|----|------|     |----|-------------------|---------|
| 1  | Luke |     |  1 | [email protected] |       1 |

First, I tried just saving into EmailAddress:

<?php

$newEmail = new Foo\Entities\Emails();
$newEmail->setEmailAddress('[email protected]');

$em->persist($newEmail);
$em->flush();
$em->clear();

The email_address field is saved, but the foreign key (name_id) is always blank.

I also tried:

<?php

$newEmail = new Foo\Entities\Emails();
$newEmail->setEmailAddress('[email protected]');

$newName = $em->getRepository('Foo\Entities\Names')->findOneBy(['id' => 1]);
$newName->addEmail($newEmail);

$em->persist($newName);
$em->flush();
$em->clear();

Same result, foreign key is ignored.

Here are my entities:

Name

/**
 * @namespace
 */
namespace Foo\Entities;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Foo\Entities\Emails;

/**
 * @ORM\Entity
 * @ORM\Table(name="names")
 */
class Names
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    protected $id;

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

    /**
     * @ORM\OneToMany(targetEntity="Emails", mappedBy="names", cascade={"persist"})
     * @ORM\JoinColumn(name="id", referencedColumnName="name_id")
     */
    private $emails;

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

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

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

    public function addEmail(Emails $email)
    {
        $this->emails->add($email);
    }

    public function getEmails()
    {
        return $this->emails;
    }
}

Emails

/**
 * @namespace
 */
namespace Foo\Entities;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="emails")
 */
class Emails
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=50)
     */
    protected $email_address;

    /**
     * @ORM\Column(type="integer")
     */
    protected $name_id;

    /**
     * @ORM\ManyToOne(targetEntity="Names", inversedBy="emails")
     * @ORM\JoinColumn(name="name_id", referencedColumnName="id")
     */
    private $names;

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

    public function setEmailAddress($value)
    {
        $this->email_address = $value;
    }
    public function getEmailAddress()
    {
        return $this->email_address;
    }

    public function setNameId($value)
    {
        $this->name_id = $value;
    }
    public function getNameId()
    {
        return $this->name_id;
    }
}

Upvotes: 1

Views: 515

Answers (1)

Jeebs24
Jeebs24

Reputation: 177

So I finally figured it out. I should have been setting Names to Emails.

Modified Emails entity:

class Emails
{
...
    public function setName(Foo\Entities\Names $name)
    {
        $this->names = $name;
    }
}

And then:

$name = $em->getRepository('Foo\Entities\Names')->findOneBy(['id' => 1]);

$newEmail = new Foo\Entities\Emails();
$newEmail->setEmailAddress('[email protected]');
$newEmail->setName($name);

$em->persist($newEmail);
$em->flush();
$em->clear();

Sets the foreign key of new email address record.

Upvotes: 1

Related Questions