2

I am trying to add a ManyToOne column to an already existing table with rows in it. I want it to be nullable=false!

Since it is not nullable, I'm trying to set a default value, but there is no option to do it. If I don't set a default value, the shema update crashes and is not able to create the foreign key since there is no row with id of 0 in the table I created

The code of the table refered by the foreign key:

<?php

namespace MyBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints;

/**
 * @ORM\Table(name="authority")
 * @ORM\Entity()
 */
class Authority
{
    /**
     * @var int
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var string
     * @Constraints\NotBlank(message="name cannot be blank.")
     * @ORM\Column(type="string")
     */
    protected $name;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="created_at", type="datetime", nullable=true)
     */
    protected $createdAt;

    /**
     * Authority constructor.
     */
    public function __construct()
    {
        $this->createdAt = new \DateTime();
    }
}

The code of the table where I want to add the foreign key:

/**
 * @var Authority
 * @ORM\ManyToOne(targetEntity="MyBundle\Entity\authority", cascade={"persist"})
 * @ORM\JoinColumn(referencedColumnName="id", nullable=false)
 */
protected $authority;

I tried:

protected $authority = 1;

or

 * @ORM\JoinColumn(referencedColumnName="id", nullable=false, default=1)

or

public function __construct()
{
    $this->authority = 1;
}

I don't want to have to change the database manually.

Liora Haydont
  • 1,252
  • 1
  • 12
  • 25
  • Possible duplicate of [Symfony2 - Set default value in entity constructor](https://stackoverflow.com/questions/20304448/symfony2-set-default-value-in-entity-constructor) – Tony Chiboucas Nov 06 '17 at 22:52
  • `$this->authority` can only be set as an object. One way or another, you'll have to get the actual entity, and include it in your entity's `$authority` property prior to persisting. `$this->authority = AuthorityRepository->find(1);` – Tony Chiboucas Nov 06 '17 at 22:56
  • I understand that but if I don't set a default value I can't run the "database:schema:update", there is an error when it tries to apply the foreign key since the column is not null it is set to 0 when the column is created and I have no authority with an id of 0 – Liora Haydont Nov 06 '17 at 23:00
  • Alternatively, you can use [Reference Proxies](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/advanced-configuration.html#reference-proxies), but this still requires an instance of EntityManager. `$this->authority = $em->getReference('Authority', 1);` – Tony Chiboucas Nov 06 '17 at 23:01
  • My suggestion is to use some method to set the default, either in the _constructor, a PrePersist handler, or PrePersist event listener, to set that value to an acual instance of the object, or to a reference proxy for that object. Ultimately, there is no method to directly modify the id column of a relationship field, aside from bypassing Doctrine entirely. Instead, set the `$authority` property of your entity to the whole `Authority (id=1)` object. – Tony Chiboucas Nov 06 '17 at 23:07
  • The problem is that your existing table already has rows in it? I don't see anyway Doctrine can do what you want. I think you will need to manually do an alter table with a default value: https://stackoverflow.com/questions/3569347/adding-a-new-sql-column-with-a-default-value – Cerad Nov 07 '17 at 00:22

3 Answers3

2
/**
 * @var Authority
 * @ORM\ManyToOne(targetEntity="MyBundle\Entity\authority", cascade={"persist"})
 * @ORM\JoinColumn(referencedColumnName="id", nullable=false, columnDefinition="INT DEFAULT 1")
 */
protected $authority;

This do the trick in auto generated migration class.

jjgarcía
  • 589
  • 1
  • 4
  • 26
0

You can set the default for the primary key of the referenced table. Look at the options={"default"=1}:

/**
 * @ORM\Table(name="authority")
 * @ORM\Entity()
 */
class Authority
{
    /**
     * @var int
     * @ORM\Id
     * @ORM\Column(type="integer", options={"default"=1})
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
xabitrigo
  • 1,341
  • 11
  • 24
-1

/**

  • @ORM\ManyToOne(targetEntity="App\Entity\Enumeration\TypeCompte")
  • @ORM\JoinColumn(name="IdTypeCompte", referencedColumnName="Id", nullable=false, columnDefinition="INT DEFAULT 1")

*/

private $typeCompte;