我正面临着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表中,我可以正确地看到正确的关联。
为什么要保存旅行,第二次尝试插入新体验?
提前致谢,对不起我的英语。