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 对象(可能有效,但做法不好(
columnDefinition
教义列注释参考¶
优点:您可以设置自己的列定义
缺点:doctrine orm:schema-tool
被 Doctrine 使用(如果您使用它(,会感到困惑,并且总是报告具有自定义columnDefinition
的列已更改。 因为它将始终告诉您为列定义运行 change 命令,如下所述:
如果您使用"columnDefinition",SchemaTool 将不再正确检测列上的更改。
例
/**
* @ManyToOne(targetEntity="YourType")
* @JoinColumn(
* name="your_type_id",
* referencedColumnName="id",
* nullable=false,
* columnDefinition="INT NOT NULL DEFAULT 1"
* )
*/
private $yourType;
请注意,单独使用 columnDefinition
可用于生成迁移,但会破坏 ORM 上下文并可能导致 FK 完整性问题。您仍然需要将对象关联添加到 ORM 以持久化实体。查看奥克拉米乌斯的警告
例:
(new PublicText())
->getFoo(); //null - expected object(Foo)#1 (1) { ["id"] => int(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();
<小时 />鉴别器映射
尽管根据用例并不总是可行的。定义实体默认值的方法之一是创建具有单个表继承的DiscriminatorMap
。http://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 string [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
使用注释,您可以在@ORM''列上使用:options={"default" = YourValue},因此在yaml中我认为您可以添加
options:
default: yourValue
我不确定,我给你一个主意...