使用Doctrine2 Symfony将元素放入DB时出错

时间:2016-04-17 17:35:25

标签: php symfony orm doctrine-orm

我正在尝试将一个名为question tag的表放入一个元素中:

//the question with Id 1 exist already
$question = new Question();
$question->setId(1);

//the tag with name PYTHON exist already
$tag = new Tag();
$tag->setName("PYTHON");

$questionTag = new QuestionTag();
$questionTag->setQuestion($question);
$questionTag->setTag($tag);

//now I call a service to put the item into DB
$questionTagPF = $this->get('facade.QuestionTagFacade');
$res = $questionTagPF->create($questionTag);

这是保存实体的方法:

public function create( $entity ) {
    $this->entityManager->getConnection()->beginTransaction();
    try {
        $this->entityManager->persist($entity);
        $this->entityManager->flush();
        $this->entityManager->getConnection()->commit();
        return true;
    } catch ( Exception $e ) {
        $this->entityManager->getConnection()->rollBack();
        return false;
    }
}

这些是实体类: 关系(问题和标签之间):

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * QuestionTag
 *
 * @ORM\Table(name="question_tag", indexes={@ORM\Index(name="question", columns={"question"}), @ORM\Index(name="index_question_tag", columns={"tag"})})
 * @ORM\Entity
 */
class QuestionTag
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var \AppBundle\Entity\Question
     *
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Question", cascade={ "persist" })
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="question", referencedColumnName="id")
     * })
     */
    private $question;

    /**
     * @var \AppBundle\Entity\Tag
     *
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Tag", cascade={ "persist" })
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="tag", referencedColumnName="name")
     * })
     */
    private $tag;



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

    /**
     * Set question
     *
     * @param \AppBundle\Entity\Question $question
     *
     * @return QuestionTag
     */
    public function setQuestion(\AppBundle\Entity\Question $question = null)
    {
        $this->question = $question;

        return $this;
    }

    /**
     * Get question
     *
     * @return \AppBundle\Entity\Question
     */
    public function getQuestion()
    {
        return $this->question;
    }

    /**
     * Set tag
     *
     * @param \AppBundle\Entity\Tag $tag
     *
     * @return QuestionTag
     */
    public function setTag(\AppBundle\Entity\Tag $tag = null)
    {
        $this->tag = $tag;

        return $this;
    }

    /**
     * Get tag
     *
     * @return \AppBundle\Entity\Tag
     */
    public function getTag()
    {
        return $this->tag;
    }
}

问题实体:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Question
 *
 * @ORM\Table(name="question", indexes={@ORM\Index(name="index_question_title", columns={"title"}), @ORM\Index(name="index_question_creation", columns={"creation_date"}), @ORM\Index(name="index_question_completed", columns={"completed"}), @ORM\Index(name="index_question_subject", columns={"subject"}), @ORM\Index(name="index_question_user", columns={"user_platform"})})
 * @ORM\Entity
 */
class Question
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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

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

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="creation_date", type="date", nullable=false)
     */
    private $creationDate;

    /**
     * @var boolean
     *
     * @ORM\Column(name="completed", type="boolean", nullable=true)
     */
    private $completed = '0';

    /**
     * @var integer
     *
     * @ORM\Column(name="level", type="integer", nullable=true)
     */
    private $level = '1';

    /**
     * @var \AppBundle\Entity\Subject
     *
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Subject", cascade={ "persist" })
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="subject", referencedColumnName="name")
     * })
     */
    private $subject;

    /**
     * @var \AppBundle\Entity\UserPlatform
     *
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\UserPlatform", cascade={ "persist" })
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="user_platform", referencedColumnName="username")
     * })
     */
    private $userPlatform;


    /**
     * Set id
     *
     * @param string $id
     *
     * @return Question
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

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

    /**
     * Set title
     *
     * @param string $title
     *
     * @return Question
     */
    public function setTitle($title)
    {
        $this->title = $title;

        return $this;
    }

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

    /**
     * Set text
     *
     * @param string $text
     *
     * @return Question
     */
    public function setText($text)
    {
        $this->text = $text;

        return $this;
    }

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

    /**
     * Set creationDate
     *
     * @param \DateTime $creationDate
     *
     * @return Question
     */
    public function setCreationDate($creationDate)
    {
        $this->creationDate = $creationDate;

        return $this;
    }

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

    /**
     * Set completed
     *
     * @param boolean $completed
     *
     * @return Question
     */
    public function setCompleted($completed)
    {
        $this->completed = $completed;

        return $this;
    }

    /**
     * Get completed
     *
     * @return boolean
     */
    public function getCompleted()
    {
        return $this->completed;
    }

    /**
     * Set level
     *
     * @param integer $level
     *
     * @return Question
     */
    public function setLevel($level)
    {
        $this->level = $level;

        return $this;
    }

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

    /**
     * Set subject
     *
     * @param \AppBundle\Entity\Subject $subject
     *
     * @return Question
     */
    public function setSubject(\AppBundle\Entity\Subject $subject = null)
    {
        $this->subject = $subject;

        return $this;
    }

    /**
     * Get subject
     *
     * @return \AppBundle\Entity\Subject
     */
    public function getSubject()
    {
        return $this->subject;
    }

    /**
     * Set userPlatform
     *
     * @param \AppBundle\Entity\UserPlatform $userPlatform
     *
     * @return Question
     */
    public function setUserPlatform(\AppBundle\Entity\UserPlatform $userPlatform = null)
    {
        $this->userPlatform = $userPlatform;

        return $this;
    }

    /**
     * Get userPlatform
     *
     * @return \AppBundle\Entity\UserPlatform
     */
    public function getUserPlatform()
    {
        return $this->userPlatform;
    }
}

标签实体:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Tag
 *
 * @ORM\Table(name="tag")
 * @ORM\Entity
 */
class Tag
{
    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=20)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     */
    private $name = '';


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

        return $this;
    }

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

当我尝试将值放入表question_tag时出现此错误:

An exception occurred while executing 'INSERT INTO tag (name) VALUES (?)' with params ["PYTHON"]:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'PYTHON' for key 'PRIMARY'

为什么呢?

如果数据库中已存在值,则不应该避免输入值?如果这应该明确,我该怎么办?

谢谢

2 个答案:

答案 0 :(得分:0)

在Symfony2中你有这个称为Validators的东西,他们的工作是根据约束验证一个对象,所以在你的情况下你可以在你的标签实体中使用以下约束

http://symfony.com/doc/current/reference/constraints/UniqueEntity.html

然后调用控制器中的验证器服务。如果对类使用FormTypes,则可以避免此步骤,它们会使用验证程序服务自动验证对象。

http://symfony.com/doc/current/book/forms.html

实际上你可以使用表单验证数据结构..但这是offtopic

.....

你可以这样做的另一种方法是选择你要插入的标签并检查是否有结果如果不好那么你可以插入标签如果它存在你只是从数据库中恢复它并使用现有标签

答案 1 :(得分:0)

问题在于我给方法将数据放入db的参数,所以这段代码:

//the question with Id 1 exist already
$question = new Question();
$question->setId(1);

//the tag with name PYTHON exist already
$tag = new Tag();
$tag->setName("PYTHON");

$questionTag = new QuestionTag();
$questionTag->setQuestion($question);
$questionTag->setTag($tag);

//now I call a service to put the item into DB
$questionTagPF = $this->get('facade.QuestionTagFacade');
$res = $questionTagPF->create($questionTag);

必须这样写:

//the question with Id 1 exist already
$question = $this->getDoctrine()->getManager()->getReference('AppBundle:Question',"1");

//the tag with name PYTHON exist already
$tag = $this->getDoctrine()->getManager()->getReference('AppBundle:Tag',"PYTHON");

$questionTag = new QuestionTag();
$questionTag->setQuestion($question);
$questionTag->setTag($tag);

//now I call a service to put the item into DB
$questionTagPF = $this->get('facade.QuestionTagFacade');
$res = $questionTagPF->create($questionTag);

问题是要在关系中插入一个值,你必须通过管理器获取值!