Default value in Doctrine

How do I set a default value in Doctrine 2?


Solution 1:

<?php
/**
 * @Entity
 */
class myEntity {
    /**
     * @var string
     *
     * @ORM\Column(name="myColumn", type="integer", options={"default" : 0})
     */
    private $myColumn;
    ...
}

Note that this uses SQL DEFAULT, which is not supported for some fields like BLOB and TEXT.

Solution 2:

Database default values are not "portably" supported. The only way to use database default values is through the columnDefinition mapping attribute where you specify the SQL snippet (DEFAULT cause inclusive) for the column the field is mapped to.

You can use:

<?php
/**
 * @Entity
 */
class myEntity {
    /**
     * @var string
     *
     * @Column(name="myColumn", type="string", length="50")
     */
    private $myColumn = 'myDefaultValue';
    ...
}

PHP-level default values are preferred as these are also properly available on newly created and persisted objects (Doctrine will not go back to the database after persisting a new object to get the default values).

Solution 3:

Set up a constructor in your entity and set the default value there.

Solution 4:

Use:

options={"default":"foo bar"}

and not:

options={"default"="foo bar"}

For instance:

/**
* @ORM\Column(name="foo", type="smallint", options={"default":0})
*/
private $foo

Solution 5:

Update

One more reason why read the documentation for Symfony will never go out of trend. There is a simple solution for my specific case and is to set the field type option empty_data to a default value.

Again, this solution is only for the scenario where an empty input in a form sets the DB field to null.

Background

None of the previous answers helped me with my specific scenario but I found a solution.

I had a form field that needed to behave as follow:

  1. Not required, could be left blank. (Used 'required' => false)
  2. If left blank, it should default to a given value. For better user experience, I did not set the default value on the input field but rather used the html attribute 'placeholder' since it is less obtrusive.

I then tried all the recommendations given in here. Let me list them:

  • Set a default value when for the entity property:
<?php
/**
 * @Entity
 */
class myEntity {
    /**
     * @var string
     *
     * @Column(name="myColumn", type="string", length="50")
     */
    private $myColumn = 'myDefaultValue';
    ...
}
  • Use the options annotation:
@ORM\Column(name="foo", options={"default":"foo bar"})
  • Set the default value on the constructor:
/**
 * @Entity
 */
class myEntity {
    ...
    public function __construct()
    {
        $this->myColumn = 'myDefaultValue';
    }
    ...
}
None of it worked and all because of how Symfony uses your Entity class.

IMPORTANT

Symfony form fields override default values set on the Entity class. Meaning, your schema for your DB can have a default value defined but if you leave a non-required field empty when submitting your form, the form->handleRequest() inside your form->isValid() method will override those default values on your Entity class and set them to the input field values. If the input field values are blank, then it will set the Entity property to null.

http://symfony.com/doc/current/book/forms.html#handling-form-submissions

My Workaround

Set the default value on your controller after form->handleRequest() inside your form->isValid() method:

...
if ($myEntity->getMyColumn() === null) {
    $myEntity->setMyColumn('myDefaultValue');
}
...

Not a beautiful solution but it works. I could probably make a validation group but there may be people that see this issue as a data transformation rather than data validation, I leave it to you to decide.


Override Setter (Does Not Work)

I also tried to override the Entity setter this way:

...
/**
 * Set myColumn
 *
 * @param string $myColumn
 *
 * @return myEntity
 */
public function setMyColumn($myColumn)
{
    $this->myColumn = ($myColumn === null || $myColumn === '') ? 'myDefaultValue' : $myColumn;

    return $this;
}
...

This, even though it looks cleaner, it doesn't work. The reason being that the evil form->handleRequest() method does not use the Model's setter methods to update the data (dig into form->setData() for more details).