0

我使用 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 实体(未持久化)在数据库中是唯一的,因此我们创建一个新实体(持久化)。
4

1 回答 1

1

创建您自己的 getOrCreate()方法并在您的侦听器中调用它。看到这篇文章 Symfony2 学说 FindOneOrCreate

另一种可能性是数据转换器。http://symfony.com/doc/current/cookbook/form/data_transformers.html

于 2013-07-31T13:44:32.037 回答