Symfony2 ManyToMany关系也保存了现有的相关实体

时间:2017-07-12 14:21:11

标签: symfony doctrine-orm many-to-many symfony-2.8

我正面临着Symfony2.8上Doctrine ManyToMany实体关系的问题。 我有实体旅行,可以由许多经验实体组成。

这是我的行程定义:

<a class="container" id="1" href="#">One</a>
<a class="container" id="2" href="#">Two</a>
<a class="container" id="3" href="#">Three</a>

另一方面,我有经验实体:

namespace MyBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Trip
 *
 * @ORM\Table(name="trip")
 * @ORM\Entity(repositoryClass="MyBundle\Repository\TripRepository")
 * @ORM\HasLifecycleCallbacks
 */
class Trip
{
    use ORMBehaviors\Timestampable\Timestampable;
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;    

    // other fields

    /**
     * @ORM\ManyToMany(targetEntity="MyBundle\Entity\Experience", inversedBy="trips")
     * @ORM\JoinTable(name="experience_trip",
     *  joinColumns={
     *     @ORM\JoinColumn(name="trip_id", referencedColumnName="id")
     *  },
     *  inverseJoinColumns={
     *     @ORM\JoinColumn(name="experience_id", referencedColumnName="id")
     *  }
     * )
     */
    private $experiences;

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

    // other setters and getters

    /**
     * Add experience
     *
     * @param \MyBundle\Entity\Experience $experience
     *
     * @return Trip
     */
    public function addExperience(\MyBundle\Entity\Experience $experience)
    {
        $this->experiences[] = $experience;

        return $this;
    }

    /**
     * Remove experience
     *
     * @param \MyBundle\Entity\Experience $experience
     */
    public function removeExperience(\MyBundle\Entity\Experience $experience)
    {
        $this->experiences->removeElement($experience);
    }

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

}

在控制器中,用户可以生成一个新的Trip,将对象放入会话中以将其调用直到真正的关联。

namespace MyBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Experience
 *
 * @ORM\Table(name="experience")
 * @ORM\Entity(repositoryClass="MyBundle\Repository\ExperienceRepository")
 */
class Experience
{

    use ORMBehaviors\Translatable\Translatable;
    use ORMBehaviors\Timestampable\Timestampable;


    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToMany(targetEntity="MyBundle\Entity\Trip", mappedBy="experiences")
     */
    private $trips;

    // other fields

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

    // other setters and getters

    /**
     * Add trip
     *
     * @param \MyBundle\Entity\Trip $trip
     *
     * @return Experience
     */
    public function addTrip(\MyBundle\Entity\Trip $trip)
    {
        $this->trips[] = $trip;

        return $this;
    }

    /**
     * Remove trip
     *
     * @param \MyBundle\Entity\Trip $trip
     */
    public function removeTrip(\MyBundle\Entity\Trip $trip)
    {
        $this->trips->removeElement($trip);
    }

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

问题所在。 在第一次调用时,它像魅力一样工作,添加experience_trip条目,一切正常。 在第二次电话会议中,持续不同的经验,寻找经验实体的级联,抛出错误:

  

通过关系'MyBundle \ Entity \ Trip #experience'找到了一个新实体,该关系未配置为对实体进行级联持久操作:。要解决此问题:在此未知实体上显式调用EntityManager#persist()或在映射中配置级联持久保存此关联,例如@ManyToOne(..,cascade = {“persist”})。

这是因为尝试添加新的体验实体,事实上,使用/** * @Route("/add-experience", name="add_experience") */ public function addExperienceAction(Request $request) { $experienceId = $request->query->get('experience'); $em = $this->getDoctrine()->getManager(); $experience = $em->getRepository('MyBundle:Experience')->find($experienceId); if (!$experience || !get_class($experience) == 'MyBundle:Experience') { $response = array("message" => "Experience not found", "success" => false); return new Response(json_encode($response)); } $session = $request->getSession(); $trip = $session->get('trip'); // This service only construct parameters $searchParameters = $this->get('mybundle.search')->buildSearchParameters(); if (!$trip) { $trip = new Trip(); $trip->setStartDate($searchParameters['startDate']); $trip->setEndDate($searchParameters['endDate']); } $trip->addExperience($experience); $trip->setClient($this->getUser()); /** user can be null */ $em->persist($trip); $em->flush(); $session->set('trip', $trip); $response = array("message" => "Experience n.$experienceId added correctly", "success" => true); return new Response(json_encode($response)); } ,由于字段的唯一性,在体验重复上生成sql异常。

相同模型由Sonata TripAdmin类正确管理,而不是试图在持续存在的情况下添加新体验,而不是避免创建ExperienceTrip实体。在experience_trip表中,我可以正确地看到正确的关联。

为什么要保存旅行,第二次尝试插入新体验?

提前致谢,对不起我的英语。

1 个答案:

答案 0 :(得分:0)

我自己找到了解决方案,也感谢this comment

由于某种原因,会话中的实体是分离的,并且不是有效的实体。所以坚持尝试再次添加它。