You're right, the difference is that the value is being set on different levels. To elaborate, if you create a default value using:
/**
* @var string $variable
*
* @ORM\Column(name="variable", type="string", nullable=true)
*/
private $variable = "default_value";
When do you create a new object with the default value.
$a = new MyClass();
$a->getVariable(); // -> 'default_value'
So the actual default value is accessible immediately. If you use the second approach:
/**
* @var string $variable
*
* @ORM\Column(name="variable", type="string", nullable=true,options={"default" = "default_value"})
*/
private $variable;
This will cause that the schema in DB will contain default value for the column so the value will be accessible after you save the entity
$a = new MyClass();
$a->getVariable(); // -> null
$em->perist($a);
$em->flush();
$a->getVariable(); // -> 'default_value'
I would say this is the basic difference. It really depends of where you want to control your default values and when you want to have them.
In my opinion, in most of the cases the assignment in the entity itself is better, since if you want to change the value later in the system, all you need to do is update the value on the entity.
If you will be using the default in the database, then updating to a different value will need to update the annotation and then create a migration to alter the default value in the DB field
UPDATE (Migration question):
In case you use default value specified in Doctrine annotation and you're using Doctrine migrations bundle for the Symfony project and you will write your migration for this class manually (not by using php app/console doctrine:migrations:diff
), you need to specify manually the default as an option. The annotation itself just tells how the column definition should look like.
If the default value is set only in PHP, i.e. private $variable = 'default_value';
migration bundle will not be affected by it at all. That means that if you run php app/console doctrine:migrations:diff
the DEFAULT
value for the field won't be filled in. Of course if you write the migration yourself, the default value in the database will be there only if you fill it automatically in.
To sum the migration budle functionality - the automatically generated migrations are affected only by default value in @ORM\Column
annotation.