我使用 Symfony2 和教义。我目前有一个名为 Person 的实体。该实体以一对多关系(作为多对一单向关系)与其他一些实体相关。我希望每个 Person 实体都是唯一的(我通过使用 UniqueConstraint 注释在我的数据库中所做的)。
为了清楚起见,我假设我有两个名为 Home 和 Car 的实体,它们都与目标实体 Person 具有多对一关系。
然后我使用表单来创建或编辑我的实体 Car 和 Home。在这些表单中,我显示了一个嵌入式表单来创建一个 Person 实体或选择一个现有的。我解释一下:嵌入表单的第一个字段是人名。当用户键入人名时,将显示现有人的列表(使用 JQuery 自动完成 UI),如果用户选择其中一个,其他字段将自动完成。
问题是当用户与现有人员一起提交表单时,我发现了一个完整性错误(我知道为什么,因为我的唯一约束)。
第一个解决方法之一是将 id 字段添加为嵌入表单中的隐藏输入。但随后用户可以编辑其他字段并破坏当前实体。所以不行。
如果 Person 已经存在,另一个可能是防止控制器中的持久性,但是因为我在许多其他实体中使用它。我将不得不复制我的代码,我不想这样做,因为唯一约束与 Person 实体相关,而不是与 Car 或 Home 实体相关。所以又不行了。
我正在研究的解决方法是使用 PrePersist 侦听器等待 Person 实体,但我不知道如何取消持久化(也许这是不可能的)。我有以下代码:
public function prePersist(LifecycleEventArgs $args) {
$entity = $args->getEntity();
if($entity instanceof Personne) {
$em = $args->getEntityManager();
$persons = $em->getRepository('MyBundle:Person')->findBy(array(
// unique fields
));
if(count($persons) > 0) {
// ... ???
}
}
我已经尝试过 $em->detach 但它没用,因为我已经在持久化实体。
我想要的只是一种“获取或创造”。我解释一下,只有两种情况:
- Person 实体(未持久化)具有与数据库中存在的所有字段相同的字段(id 字段除外),因此 Person 实体是数据库中的一个。我必须用数据库中的“替换”它;
- Person 实体(未持久化)在数据库中是唯一的,因此我们创建一个新实体(持久化)。