Symfony 3中UniqueEntity验证更新操作

3
我遇到了UniqueEntity验证问题。 我有一个名为“internal_asset_number”的字段,它应该是唯一的,并且在创建时运行良好。但是在更新时,当我使用相同值编辑现有当前数据时,它显示“已经存在具有该内部编号的资产!”,但实际上不应该这样,因为这是同一条记录。
实体:
/**
* Asset
*
* @ORM\Table(schema="assets", name="asset", uniqueConstraints=    {@ORM\UniqueConstraint(name="uk_asset_internal_asset_number_client_id", columns={"internal_asset_number", "client_id"})})
* @ORM\Entity(repositoryClass="Api\AssetBundle\Entity\AssetRepository")
* @UniqueEntity(fields={"internalAssetNumber"}, groups={"post", "put"}, message="There is already an asset with that internal number!")
*/
class Asset
   {
   /**
    * @var guid
    *
    * @ORM\Column(name="id", type="string")
    * @ORM\Id
    * @ORM\GeneratedValue(strategy="UUID")
    */
   private $id;

   /**
    * @var string
    *
    * @ORM\Column(name="client_id", type="string", length=255, nullable=false)
    */
   private $clientId;

   /**
    * @var string
    *
    * @ORM\Column(name="internal_asset_number", type="string", length=255, nullable=true, unique=true)
    */
   private $internalAssetNumber;

更新方法:

public function putAssetAction(Request $request, $id)
{
    $data = $this->deserializer('Api\AssetBundle\Entity\Asset', $request, 'put');
    if ($data instanceof \Exception) {
        return View::create(['error' => $data->getMessage()], 400);
    }

    $validator = $this->get('validator');
    $errors = $validator->validate($data, null, 'put');

    if (count($errors) > 0) {         
        $errorsResponse = [];
        foreach ($errors as $error) {
            $errorsResponse = $error->getMessage();
        }
        return View::create(array('error' => $errorsResponse), 400);
    }
    ...

你如何进行更新?你所说的“blocked”是什么意思?你遇到了哪个错误? - Jakub Matczak
@JakubMatczak 我得到了错误消息,因为它是重复的。但在这种情况下,我使用相同的值更新了相同的条目,所以不应该发生这种情况。我已经更新了我的问题。 - Cosmin
1
当数据库中存在给定条件的条目时,UniqueEntityValidator 将检查正在验证的对象和找到的对象是否相同(即执行标识检查)。在您的情况下,此检查失败,因为正在验证的对象是反序列化的对象,而不是由 Doctrine 管理的对象。 - xabbuh
@xabbuh 感谢您的解释。 - Cosmin
1个回答

4

正如 @xabbuh 所评论的那样,问题在于您在更新后持久化的实体未经过entityManager检索,因此当您持久化它时,实体管理器认为它是一个新实体。

以下是解决方法:

$entityManager->merge($entity);

这将告诉实体管理器使用已管理的实体来合并您的序列化实体。
关于merge()的更多解释请参考:https://dev59.com/zGUo5IYBdhLWcg3wtRMx#15838232

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接