Default Value in Doctrine

Default value in Doctrine

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).

Doctrine default value vs null insert

Like @Cerad commented, you just need to initialize the property in your actual entity class

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

Doctrine ORM default value of none existing entity

In such case you cannot set this layout_id as part of the composite key. This is because of the foreign key constraint. Either your layout_id has to be nullable (meaning it cannot be part of the composite key) or you have to make a row in your layout table with id 0 (so it can be used as an identifier).

A solution could be to not use a composite key but instead add a primary key column for uniquely identifying your entity (surrogate key).

Symfony - Doctrine Annotations default value for a foreign key

In annotations it's not possible. There are a few different methods you can try, I suggest a pre-persist event.

Possible duplicate

Doctrine : Default value on joinColumn field

Please note that using columnDefinition alone will work for generating migrations but will break the ORM context and potentially cause FK integrity issues. You will still need to add the object association to the ORM for persisting entities. See warnings from Ocramius

Example:

(new PublicText())
->getFoo(); //null - expected object(Foo)#1 (1) { ["id"] => int(1) }

I have seen many ways to achieve this in doctrine 2.

Constructor

In general, the quickest way and what most users do is require an association in the constructor.

public function __construct(Foo $foo)
{
$this->foo = $foo;
}

Then you can use getReference to retrieve it in your controller without needing to query the database. See http://doctrine-orm.readthedocs.org/en/latest/reference/advanced-configuration.html#reference-proxies

$foo = $em->getReference('app:Foo', 1);
$text = new \Path\To\Entity\PublicText($foo);
$em->persist($text);
$em->flush();


LifeCycleEvents

My preferred way Another method to set the default value with most ManyToOne relationships is to utilize the LifeCycleEvents http://doctrine-orm.readthedocs.org/en/latest/reference/events.html

Though it does have some caveats to be aware of. So be sure to RTM before implementing into production environments. In this case it should work fine, but I don't know your entire mapping structure.

 use Doctrine\ORM\Event\LifecycleEventArgs;

/**
* @Entity
* @HasLifeCycleEvents
*/
class PublicText
{
// ...

/**
* @PrePersist
* @param \Doctrine\ORM\Event\LifecycleEventArgs $event
*/
public function onPrePersist(LifecycleEventArgs $event)
{
if (false === empty($this->foo)) {
return;
}
$this->foo = $event->getEntityManager()->getReference('app:Foo', 1);
}
}

Then in your controller.

$text = new \Path\To\Entity\PublicText;
$em->persist($text); //retrieve and set foo if not set in the Entity Event.
$em->flush();


Repository Method

Another option within your Entity is to just set the property's value using a Repository.

Define Repository Class in Entity

/**
* @Entity(repositoryClass="PublicTextRepo")
*/
class PublicText
{
// ...
}

Repository

use Doctrine\ORM\EntityRepository;

class PublicTextRepo extends EntityRepository
{
public function create()
{
$text = new \Path\To\Entity\PublicText;
$foo = $this->_em->getReference('app:Foo', 1);
$text->setFoo($foo );
return $text;
}
}

Then in your controller you can then do

$text = $em->getRepository('app:PublicText')->create();
$em->persist($text);
$em->flush();


Discriminator Map

Though not always viable depending on the use case. One of the ways I go about defining a default value of an Entity is creating a DiscriminatorMap with single table inheritance. http://doctrine-orm.readthedocs.org/en/latest/reference/inheritance-mapping.html#single-table-inheritance.

This way when the object is created the default value is automatically set in the database, and locks the object as that type. The issue is that the resulting value is not an object like it is in the other methods above.

To get the object's discriminator static value, you can use constants within the objects you define.

/**
* @Entity
* @InheritanceType("SINGLE_TABLE")
* @Table(name="user")
* @DiscriminatorColumn(name="type", type="string")
* @DiscriminatorMap({Person::TYPE="Person", Employee::TYPE="Employee"})
*/
class Person
{
const TYPE = 'person';

/**
* @return string [person|employee]
*/
public function getType()
{
return $this::TYPE;
}
// ...
}

/**
* @Entity
*/
class Employee extends Person
{
const TYPE = 'employee';
// ...
}

Then all you need to do in your controller is.

$employee = new \Path\To\Entity\Employee;
$em->persist($employee); //inserts with `user.type` as `employee`
$em->flush();

echo $employee->getType(); //employee

What is the best way to set defaults values of a Symfony object?

I would recommend you setting default values for a properties if it is possible. If not, use the constructor. Keep in mind that in doctrine ORM constructor can be omitted in some cases.
Also, don't forget to set annotation for a column declaration

<?php
/**
* @Entity
*/
class City {
/**
* @var string
*
* @Column(type="string", length="50", options={"default" : "Washington DC"})
*/
private $name = 'Washington DC';
...
}

Default column value with Doctrine2 and Symfony2 using YAML?

I think you misunderstood annotations somehow because the default value is set via plain php.

/**
* @ORM\Column(type="bool") <- This is an annotation
*/
protected $is_visible;

public function __construct()
{
$this->products = new ArrayCollection(); // <- This is not an annotation
$this->is_visible = true; // <- This is not an annotation
}

There is no difference using the YAML mapping for the default value. The reason is simple, here how you class is looking with annotations:

use Doctrine\Common\Collections\ArrayCollection;

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

/**
* @ORM\OneToMany(targetEntity="Product", mappedBy="category")
*/
protected $products;

/**
* @ORM\Column(type="bool")
*/
protected $is_visible;

public function __construct()
{
$this->products = new ArrayCollection();
$this->is_visible = true; // Default value for column is_visible
}
}

And this is how it looks with YAML mapping:

    use Doctrine\Common\Collections\ArrayCollection;

class Category
{
protected $id;
protected $products;
protected $is_visible;

public function __construct()
{
$this->products = new ArrayCollection();
$this->is_visible = true; // Default value for column is_visible
}
}

The difference in the second example is there is no more annotations, since the mapping is done via YAML. The construction of the class is done exactly the same. Thus, default values are set at construction time which is done in plain PHP.

There is no difference between annotations and YAML mapping for this task. So, bottom line, you need to edit the generated PHP class to put your default values. There is no way you can set it in YAML and let doctrine put this code for you, at least, at the time we speak.

Maybe I misunderstood your question :), if it is the case, don't hesitate to correct me.

Hope it helps.

Regards,

Matt



Related Topics



Leave a reply



Submit