Mysql 条令2@Gedmo\SoftDelete和unique字段

Mysql 条令2@Gedmo\SoftDelete和unique字段,mysql,symfony,doctrine-orm,Mysql,Symfony,Doctrine Orm,当我有唯一字段时,@Gedmo\SoftDeleteable有问题。 如果我从表中删除一些行并创建一个try-put新记录,并且通过使用该名称给出mi错误: SQLSTATE[23000]:完整性约束冲突:密钥“UNIQ**************”的1062个重复条目“weqwewqe1” 如何在正确的位置将此消息更改为验证表单消息? 并且应该给我发送一个记录已经存在的消息表单 我的实体: /** * @ORM\Entity(repositoryClass = "Eteam\Page

当我有唯一字段时,@Gedmo\SoftDeleteable有问题。 如果我从表中删除一些行并创建一个try-put新记录,并且通过使用该名称给出mi错误:

SQLSTATE[23000]:完整性约束冲突:密钥“UNIQ**************”的1062个重复条目“weqwewqe1”

如何在正确的位置将此消息更改为验证表单消息?

并且应该给我发送一个记录已经存在的消息表单

我的实体:

    /**
 * @ORM\Entity(repositoryClass = "Eteam\PageBundle\Entity\Repository\PageRepository")
 * @ORM\Table(name = "page")
 * @ORM\HasLifecycleCallbacks
 * @Gedmo\SoftDeleteable(fieldName = "deletedDate", timeAware = false)
 *
 * @UniqueEntity(fields = {"name"})
 * @UniqueEntity(fields = {"slug"})
 */
class Page
{
    /**
     * @ORM\Column(name = "id", type = "integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy = "AUTO")
     */
    private $id;

    /**
     * @ORM\Column(name = "name", type = "string", length = 120, unique = true)
     *
     * @Assert\NotBlank
     * @Assert\Length(
     *      min = 3,
     *      max = 120
     * )
     */
    private $name;

    /**
     * @ORM\Column(name = "slug", type = "string", length = 120, unique = true)
     *
     * @Assert\NotBlank
     * @Assert\Length(
     *      min = 3,
     *      max = 120
     * )
     */
    private $slug;

    /**
     * @ORM\Column(name = "type", type = "string", length = 50)
     */
    private $type;

    /**
     * @ORM\Column(name = "status", type = "string", length = 50)
     */
    private $status;

    /**
     * @ORM\OneToMany(targetEntity = "PageContent", mappedBy = "pageId")
     */
    private $content;

    /**
     * @ORM\Column(name = "parent", type = "string", length = 50, nullable = true)
     */
    private $parent;

    /**
     * @ORM\ManyToOne(targetEntity = "PageTemplate", inversedBy = "page")
     * @ORM\JoinColumn(name = "page_template_id", referencedColumnName = "id", onDelete = "SET NULL")
     */
    private $pageTemplate;

    /**
     * @ORM\ManyToOne(targetEntity = "PageContentMap", inversedBy = "page")
     * @ORM\JoinColumn(name = "page_content_map_id", referencedColumnName = "id", onDelete = "SET NULL")
     */
    private $pageContentMapId;

    /**
     * @ORM\Column(name = "created_date", type = "datetime")
     */
    private $createdDate;

    /**
     * @ORM\Column(name = "updated_date", type = "datetime", nullable = true)
     */
    private $updatedDate;

    /**
     * @var \DateTime deletedDate
     * @ORM\Column(name = "deleted_date", type = "datetime", nullable = true)
     */
    private $deletedDate;


    /**
     * Constructor
     */
    public function __construct()
    {
        $this->content = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     *
     * @return Page
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set slug
     *
     * @param string $slug
     *
     * @return Page
     */
    public function setSlug($slug)
    {
        $genSlug = new Slugify();
        $this->slug = $genSlug->slugify($slug);

        return $this;
    }

    /**
     * Get slug
     *
     * @return string
     */
    public function getSlug()
    {
        return $this->slug;
    }

    /**
     * Set type
     *
     * @param string $type
     *
     * @return Page
     */
    public function setType($type)
    {
        $this->type = $type;

        return $this;
    }

    /**
     * Get type
     *
     * @return string
     */
    public function getType()
    {
        return $this->type;
    }

    /**
     * Set status
     *
     * @param string $status
     *
     * @return Page
     */
    public function setStatus($status)
    {
        $this->status = $status;

        return $this;
    }

    /**
     * Get status
     *
     * @return string
     */
    public function getStatus()
    {
        return $this->status;
    }

    /**
     * Set parent
     *
     * @param string $parent
     *
     * @return Page
     */
    public function setParent($parent)
    {
        $this->parent = $parent;

        return $this;
    }

    /**
     * Get parent
     *
     * @return string
     */
    public function getParent()
    {
        return $this->parent;
    }

    /**
     * Set createdDate
     *
     * @param \DateTime $createdDate
     *
     * @return Page
     */
    public function setCreatedDate($createdDate)
    {
        $this->createdDate = $createdDate;

        return $this;
    }

    /**
     * Get createdDate
     *
     * @return \DateTime
     */
    public function getCreatedDate()
    {
        return $this->createdDate;
    }

    /**
     * Set updatedDate
     *
     * @param \DateTime $updatedDate
     *
     * @return Page
     */
    public function setUpdatedDate($updatedDate)
    {
        $this->updatedDate = $updatedDate;

        return $this;
    }

    /**
     * Get updatedDate
     *
     * @return \DateTime
     */
    public function getUpdatedDate()
    {
        return $this->updatedDate;
    }

    /**
     * Set deletedDate
     *
     * @param \DateTime $deletedDate
     *
     * @return Page
     */
    public function setDeletedDate($deletedDate)
    {
        $this->deletedDate = $deletedDate;

        return $this;
    }

    /**
     * Get deletedDate
     *
     * @return \DateTime
     */
    public function getDeletedDate()
    {
        return $this->deletedDate;
    }

    /**
     * Add content
     *
     * @param \Eteam\PageBundle\Entity\PageContent $content
     *
     * @return Page
     */
    public function addContent(\Eteam\PageBundle\Entity\PageContent $content)
    {
        $this->content[] = $content;

        return $this;
    }

    /**
     * Remove content
     *
     * @param \Eteam\PageBundle\Entity\PageContent $content
     */
    public function removeContent(\Eteam\PageBundle\Entity\PageContent $content)
    {
        $this->content->removeElement($content);
    }

    /**
     * Get content
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getContent()
    {
        return $this->content;
    }

    /**
     * Set pageTemplate
     *
     * @param \Eteam\PageBundle\Entity\PageTemplate $pageTemplate
     *
     * @return Page
     */
    public function setPageTemplate(\Eteam\PageBundle\Entity\PageTemplate $pageTemplate = null)
    {
        $this->pageTemplate = $pageTemplate;

        return $this;
    }

    /**
     * Get pageTemplate
     *
     * @return \Eteam\PageBundle\Entity\PageTemplate
     */
    public function getPageTemplate()
    {
        return $this->pageTemplate;
    }

    /**
     * Set pageContentMapId
     *
     * @param \Eteam\PageBundle\Entity\PageContentMap $pageContentMapId
     *
     * @return Page
     */
    public function setPageContentMapId(\Eteam\PageBundle\Entity\PageContentMap $pageContentMapId = null)
    {
        $this->pageContentMapId = $pageContentMapId;

        return $this;
    }

    /**
     * Get pageContentMapId
     *
     * @return \Eteam\PageBundle\Entity\PageContentMap
     */
    public function getPageContentMapId()
    {
        return $this->pageContentMapId;
    }

    /**
     * @ORM\PrePersist
     * @ORM\PreUpdate
     */
    public function preSave()
    {
        if (null === $this->slug) {
            $this->setSlug($this->getName());
        }

        if (null == $this->status) {
            $this->setStatus('unpublish');
        }

    }

钢铁我还没有解决这个问题。我需要捕获此异常并发送到表单消息此名称已准备就绪。 请帮忙。

你知道“软删除”是什么意思吗?这意味着每个“删除”操作都将转换为SQL,只将一些
deleted
标记设置为
true
。若您将插入另一行,该行具有与已软删除行相同的唯一字段值,您将收到此消息

解决此问题有两种方法:

  • 使用两列创建唯一索引:原始唯一字段和
    deleted
    标志。然后,只有当您尝试为“未软删除”添加具有现有唯一字段值的行时,才会出现此错误
  • 避免发生这种冲突:您应该排除在唯一字段中添加与另一行重复的行的可能性
第二种方法是IMHO的最佳方法。

唯一约束! 您必须使用
UniqueConstraints
,而不是
uniquentity

例如,对于
name
,在
name
deletedDate
之间创建一个
UniqueConstraint

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;

/**
 * @ORM\Entity(repositoryClass="Eteam\PageBundle\Entity\Repository\PageRepository")
 * @ORM\Table(name="page",uniqueConstraints={@ORM\UniqueConstraint(name="name_unique", columns={"name", "deleted_date"})})
 * @Gedmo\SoftDeleteable(fieldName="deletedDate", timeAware=false)
 */
class Page
{
    //..
}
Mick的不错的解决方案:

/**
*@ORM\Table(name=“page”,uniqueConstraints={@ORM\UniqueConstraint(name=“name\u unique”,columns={“name”,“deleted\u date”})
*/

可能适用于postgresql,但在mysql()的某些版本中不起作用。 如何
发送到表单消息此名称已存在。
? 例如,我们可以在控制器中更改操作newAction和editAction(当在控制台中创建CRUD时):

编辑操作:

/**
 * Displays a form to edit an existing computer entity.
 *
 * @Route("/{id}/edit", name="computer_edit")
 * @Method({"GET", "POST"})
 */
public function editAction(Request $request, Computer $computer)
{
    $deleteForm = $this->createDeleteForm($computer);
    $editForm = $this->createForm('AppBundle\Form\ComputerType', $computer);
    $editForm->handleRequest($request);

    if ($editForm->isSubmitted() && $editForm->isValid()) {
        $warning = $this->uniqueInventoryNr($computer->getId(),$computer->getInventoryNr()); // added
        if ( $warning == '') { // added
            $this->getDoctrine()->getManager()->flush();

            return $this->redirectToRoute('computer_edit', array('id' => $computer->getId()));
        } else { // added
            $form_error = new \Symfony\Component\Form\FormError($warning); // added
            $editForm->addError($form_error); // added
        } // added
    }

    return $this->render('computer/edit.html.twig', array(
        'computer' => $computer,
        'edit_form' => $editForm->createView(),
        'delete_form' => $deleteForm->createView(),
    ));
}
检查功能:

private function uniqueInventoryNr($computerId,$inventoryNr)
{
    $message = '';
    $em = $this->getDoctrine()->getManager();
    $computer_in = $em->getRepository('AppBundle\Entity\Computer')->findBy(array('inventoryNr' => $inventoryNr));
    if (count($computer_in) > 0) {
        if ($computer_in[0]->getId() != $computerId) // avoid when you edit
        { 
            $message =  'Inventory number is duplicated. '; 
        }
    }
    return $message;
}

好吧,一切都很好,但我仍然不知道如何在正确的位置显示异常,以给定名称的形式已经存在?
private function uniqueInventoryNr($computerId,$inventoryNr)
{
    $message = '';
    $em = $this->getDoctrine()->getManager();
    $computer_in = $em->getRepository('AppBundle\Entity\Computer')->findBy(array('inventoryNr' => $inventoryNr));
    if (count($computer_in) > 0) {
        if ($computer_in[0]->getId() != $computerId) // avoid when you edit
        { 
            $message =  'Inventory number is duplicated. '; 
        }
    }
    return $message;
}