2

In Symfony 3 with Doctrine I'm trying to get a one-to-one unidirectional relationship with both tables sharing the same primary key working. To do so I'm trying to replicate the example on the Doctrine Association Mapping page.

However, the one-to-one uni documentation has no examples of setters and getters - and there is no definition of the id field on the target entity, either. So I tried to experiment around myself.

These are my entities:

class Country
{

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", precision=0, scale=0, nullable=false, unique=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @ORM\OneToOne(targetEntity="MySubEntity", cascade={"persist", "remove"})
     * @ORM\JoinColumn(name="id", referencedColumnName="id", nullable=true)
     */
    private $mysubentity;
    [...]
    /**
     * @return MySubEntity
     */
    public function getMySubEntity()
    {
        return $this->mysubentity;
    }

    /**
     * @param MySubEntity $mysubentity
     */
    public function setMySubEntity($mysubentity)
    {
        $this->mysubentity = $mysubentity;
    }
}

class MySubEntity
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", precision=0, scale=0, nullable=false, unique=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    [..]

    /**
     * Set id
     *
     * @param $id
     *
     * @return MySubEntity
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }
}

When I persist the country entity, I receive Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails. When inspecting the data I can see that Doctrine attempted to set the id of MySubEntity to 0.

Does anybody have an idea what I need to do for the MySubEntity $id field to be auto-populated from the Country entity?

phpPhil
  • 906
  • 1
  • 9
  • 28
  • first, I don't think nullable= true is appropriate for an id field – Adib Aroui Apr 27 '17 at 10:22
  • you have two fields with name=id – Adib Aroui Apr 27 '17 at 10:25
  • `nullable=false` for both `$id` fields. The `nullable=true` is for the relationship, as the can be an associated row, but doesn't have to (optional). Each of the two `$id` fields are located in their own individual Entity, so this should be fine. – phpPhil Apr 27 '17 at 10:29

1 Answers1

11

You need to change the JoinColumn name property to anything else but not id:

/**
 * @ORM\OneToOne(targetEntity="MySubEntity", cascade={"persist", "remove"})
 * @ORM\JoinColumn(name="mysubentity_id", referencedColumnName="id", nullable=true)
 */
private $mysubentity;

What does this do: JoinColumn tells doctrine in which database column the relation is saved. so if you call it mysub_id your main entity will have a column with that name in which the referencedColumn value will be persisted (id of your subEntity).

If you say the JoinColumn name is id which is already used by the primary key of your entity you have a conflict.

Edit:

I missed your point with sharing the same primary key. Is there any specific reason for this? But if you really need to do it for legacy reasons either look at

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/composite-primary-keys.html#use-case-2-simple-derived-identity

or the possibility to generate the primary key value of your subEntity by yourself by changing the generation strategy (NONE or custom in this case)

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#identifier-generation-strategies

Joe
  • 2,356
  • 10
  • 15
  • You are completely right, there was not really a reason why I used the same Primary Key in both tables - even though that this is valid and should work with Doctrine in my opinion. I changed the schema and instead I added a new `my_sub_entity_id` column. Then I changed the annotations to reflect the new key name and it worked straight away. Thanks for your help! – phpPhil Apr 28 '17 at 01:01