Doctrine:joinColumn字段的默认值

时间:2014-12-03 17:18:07

标签: php symfony doctrine-orm entity

symfony2和Doctrine的新手。

如何将字段foo_id(这是Foo表的引用)的默认值设置为指向Foo表的ID 1(在所有情况下都存在) )?

Me\NavigationBundle\Entity\PublicText:
    type: entity
    table: public_text
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
    fields:
        title:
            type: string
            length: '255'
            nullable: false
        content:
            type: string
            length: '2000'
            nullable: false            
    manyToOne:
        foo:
            #How to set a default value???
            targetEntity: \Me\NavigationBundle\Entity\Foo
            joinColumn:
                name: foo_id
                referencedColumnName: id   
                nullable: false 
    lifecycleCallbacks: {  }

我尝试了许多事情但没有成功:

  • 在Foo
  • 的构造函数中将默认值设置为ID 1
  • 执行请求以检索Me实体中ID 1的Foo对象(可行,但不好的做法)

3 个答案:

答案 0 :(得分:2)

Doctrine Column Annotations Reference¶

查找columnDefinition

优点:您可以设置自己的列定义

Doctrine使用的

缺点: doctrine orm:schema-tool(如果您使用它),会感到困惑,始终报告具有自定义columnDefinition的列改变。因为它总是会告诉您运行列定义的更改命令,如文档here所示:

  

如果使用“columnDefinition”,SchemaTool将不再正确检测列的更改。

示例

/**
 * @ManyToOne(targetEntity="YourType")
 * @JoinColumn(
 *     name="your_type_id",
 *     referencedColumnName="id",
 *     nullable=false,
 *     columnDefinition="INT NOT NULL DEFAULT 1"
 * )
 */
private $yourType;

答案 1 :(得分:1)

我已经看到很多方法可以在学说2中实现这一目标。

通常,最快捷的方式和大多数用户所做的是在构造函数中需要关联。

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

然后您可以使用getReference在控制器中检索它,而无需查询数据库。见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();

我设置大多数ManyToOne关系的默认值的首选方法是使用LifeCycleEvents http://doctrine-orm.readthedocs.org/en/latest/reference/events.html

虽然确实有一些需要注意的注意事项。因此,在实施到生产环境之前一定要确保RTM。在这种情况下它应该工作正常,但我不知道你的整个映射结构。

 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);
    }
}

然后在你的控制器中。

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

您的实体中的另一个选项是使用存储库设置属性的值。

在实体中定义存储库类

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

存储库

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;
   }
}

然后在您的控制器中,您可以执行

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

虽然根据用例不总是可行的。我定义实体默认值的方法之一是创建具有单表继承的DiscriminatorMaphttp://doctrine-orm.readthedocs.org/en/latest/reference/inheritance-mapping.html#single-table-inheritance

这样,在创建对象时,将在数据库中自动设置默认值,并将对象锁定为该类型。问题是结果值不是对象,就像上面的其他方法一样。

要获取对象的鉴别符static值,可以在定义的对象中使用常量。

/**
 * @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 Person|Employee
     */   
    public function getType()
    {
        return $this::TYPE;
    }
    // ...
}

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

然后你需要在你的控制器中做的就是。

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

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

答案 2 :(得分:-1)

使用注释,您可以在@ORM \ Column上使用:options = {“default”= YourValue},所以在yaml中我认为您可以添加

options:
    default: yourValue

我不确定,我想你一个想法......