亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Doctrine UniqueConstraintViolationException

Doctrine UniqueConstraintViolationException

PHP
catspeake 2022-08-05 09:41:04
我有一個SQLite表,其中包含有關圖像的數據。一列是文本字段,其中包含該圖像在網站上的顯示位置。該字段具有唯一的約束。以下是表定義:positionCREATE TABLE images (id INTEGER PRIMARY KEY, title TEXT UNIQUE NOT NULL, position TEXT UNIQUENOT NULL, caption TEXT, filename TEXT, album INTEGER NOT NULL, publicationDate TEXT, updatedTEXT, createdBy INTEGER NOT NULL, updatedBy INTEGER NOT NULL, FOREIGN KEY (createdBy) REFERENCES users(id), FOREIGN KEY(album) REFERENCES albums(id), FOREIGN KEY (updatedBy) REFERENCES users(id));并且,來自實體的相關位:/*** @ORM\Entity* @ORM\Table(name="images",indexes={*       @Index(name="publication_date", columns={"publicationDate"})},*       uniqueConstraints={@UniqueConstraint(name="unique_position", columns={"position", "fileName"})}*       )*/class Image{    /**    * @ORM\Id    * @ORM\Column(type="integer")    * @ORM\GeneratedValue    **/    protected $id;    /**    * @ORM\Column(type="string", unique=true)    */    protected $position;我可以成功地寫入表(Doctrine 保留,然后刷新),除非列上有唯一的約束沖突。當存在唯一的約束沖突時,flush() 將以靜默方式失敗(不寫入數據庫),并且應用程序將繼續執行。以下是相關代碼 - 設置并保留實體后:position        try {            $this->entityManager->flush();            $message['type'] = 'alert-info';            $message['content'] = "$title added succesfully";            return $message;        } catch (UniqueConstraintViolationException $e) {            $message['type'] = 'alert-danger';            $message['content'] = "$title could not be added " . $e;            return $this->create($message, $formVars);        } catch (Exception $e) {            $message['type'] = 'alert-danger';            $message['content'] = "$title could not be added " . $e;            return $this->create($message, $formVars);        }為什么我沒有捕捉到異常?或者,它根本沒有被扔掉嗎?
查看完整描述

1 回答

?
呼喚遠方

TA貢獻1856條經驗 獲得超11個贊

發布我上面提供的代碼實現提示,只需運行2次即可查看結果,這是控制器:


<?php


namespace App\Controller;


use App\Entity\TestEntity;

use Symfony\Component\HttpFoundation\Request;

use Symfony\Component\Routing\Annotation\Route;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

use Symfony\Component\Validator\Validator\ValidatorInterface;


class TestController extends AbstractController

{

    /**

     * @Route("/", name="test")

     */

    public function test(Request $request, ValidatorInterface $validator)

    {

        $newEntity = new TestEntity();

        $newEntity->setPosition('test');


        // In addition $form->isValid() does this for you and displays form error specified in entity

        if(($result = $validator->validate($newEntity))->count() === 0) {

            $em = $this->getDoctrine()->getManager();

            $em->persist($newEntity);

            $em->flush();

            dump('Entity persisted');

        } else {

            dump($result); // <- array of violations

            dump('Sorry entity with this position exists');

        }


        die;

    }

}

這是您的實體:


<?php


namespace App\Entity;


use Doctrine\ORM\Mapping as ORM;

use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;


/**

 * @ORM\Table(name="test_entity")

 * @ORM\Entity(repositoryClass="App\Repository\TestEntityRepository")

 * 

 * @UniqueEntity(

 *  fields={"position"},

 *  errorPath="position",

 *  message="Duplicate of position {{ value }}."

 * )

 */

class TestEntity

{

    /**

     * @ORM\Column(name="id", type="integer")

     * @ORM\Id

     * @ORM\GeneratedValue(strategy="AUTO")

     */

    private $id;


    public function getId()

    {

        return $this->id;

    }


    /**

     * @ORM\Column(name="position", type="string", length=190, unique=true) // key length limit for Mysql

     */

    private $position;


    public function getPosition()

    {

        return $this->position;

    }


    public function setPosition($position)

    {

        $this->position = $position;

        return $this;

    }

}

出于好奇,我測試了你的第一個想法,它似乎對我有用


<?php


namespace App\Controller;


use App\Entity\TestEntity;

use Symfony\Component\HttpFoundation\Request;

use Symfony\Component\Routing\Annotation\Route;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

use Symfony\Component\Validator\Validator\ValidatorInterface;


class TestController extends AbstractController

{

    /**

     * @Route("/", name="test")

     */

    public function test(Request $request, ValidatorInterface $validator)

    {

        $newEntity = new TestEntity();

        $newEntity->setPosition('test');


        try {

            $em = $this->getDoctrine()->getManager();

            $em->persist($newEntity);

            $em->flush();

        } catch(\Doctrine\DBAL\Exception\UniqueConstraintViolationException $e) {

            dump('First catch');

            dump($e);

        }

        catch(\Exception $e) {

            dump('Second catch');

            dump($e);

        }


        die;

    }

}

它導致“第一次捕獲”的轉儲,但這可能與我使用的是mysql而不是SQlite有關,這也是對Symfony驗證文檔的引用,以防您想檢查它

EDIT2

Simple Validator 類


class SomeSortOfValidator

{

    public function exists($entity, $fieldName, $fieldValue)

    {

        // Lets suppose you have entity manager autowired.

        $record = $this->em->getRepository($entity)->findOneBy([

            $fieldName => $fieldValue

        ]);

        return $record ? true : false;

    }

}


查看完整回答
反對 回復 2022-08-05
  • 1 回答
  • 0 關注
  • 182 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號