Symfony2 Many对Many关系也保存了存在的相关实体



我在Symfony2.8上遇到了一个Doctrine ManyToMany实体关系的问题。 我有实体旅行,它可以由许多体验实体组成。

这是我的行程定义:

namespace MyBundleEntity;
use DoctrineORMMapping as ORM;
use KnpDoctrineBehaviorsModel as ORMBehaviors;
use SymfonyComponentValidatorConstraints as Assert;
/**
* Trip
*
* @ORMTable(name="trip")
* @ORMEntity(repositoryClass="MyBundleRepositoryTripRepository")
* @ORMHasLifecycleCallbacks
*/
class Trip
{
use ORMBehaviorsTimestampableTimestampable;
/**
* @var int
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;    
// other fields
/**
* @ORMManyToMany(targetEntity="MyBundleEntityExperience", inversedBy="trips")
* @ORMJoinTable(name="experience_trip",
*  joinColumns={
*     @ORMJoinColumn(name="trip_id", referencedColumnName="id")
*  },
*  inverseJoinColumns={
*     @ORMJoinColumn(name="experience_id", referencedColumnName="id")
*  }
* )
*/
private $experiences;
/**
* Constructor
*/
public function __construct()
{
$this->experiences = new DoctrineCommonCollectionsArrayCollection();
}
// other setters and getters
/**
* Add experience
*
* @param MyBundleEntityExperience $experience
*
* @return Trip
*/
public function addExperience(MyBundleEntityExperience $experience)
{
$this->experiences[] = $experience;
return $this;
}
/**
* Remove experience
*
* @param MyBundleEntityExperience $experience
*/
public function removeExperience(MyBundleEntityExperience $experience)
{
$this->experiences->removeElement($experience);
}
/**
* Get experiences
*
* @return DoctrineCommonCollectionsCollection
*/
public function getExperiences()
{
return $this->experiences;
}
}

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

namespace MyBundleEntity;
use DoctrineORMMapping as ORM;
use KnpDoctrineBehaviorsModel as ORMBehaviors;
use SymfonyComponentValidatorConstraints as Assert;
/**
* Experience
*
* @ORMTable(name="experience")
* @ORMEntity(repositoryClass="MyBundleRepositoryExperienceRepository")
*/
class Experience
{
use ORMBehaviorsTranslatableTranslatable;
use ORMBehaviorsTimestampableTimestampable;

/**
* @var int
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORMManyToMany(targetEntity="MyBundleEntityTrip", mappedBy="experiences")
*/
private $trips;
// other fields
/**
* Constructor
*/
public function __construct()
{
$this->trips = new DoctrineCommonCollectionsArrayCollection();
}
// other setters and getters
/**
* Add trip
*
* @param MyBundleEntityTrip $trip
*
* @return Experience
*/
public function addTrip(MyBundleEntityTrip $trip)
{
$this->trips[] = $trip;
return $this;
}
/**
* Remove trip
*
* @param MyBundleEntityTrip $trip
*/
public function removeTrip(MyBundleEntityTrip $trip)
{
$this->trips->removeElement($trip);
}
/**
* Get trips
*
* @return DoctrineCommonCollectionsCollection
*/
public function getTrips()
{
return $this->trips;
}
}

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

/**
* @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));
}

问题。 第一次调用时,它就像一个魅力,添加experience_trip条目就可以了。 在第二次调用时,具有不同的经验,行程的持久性正在查找体验实体上的级联,抛出错误:

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

这是因为尝试添加新的体验实体,实际上,由于字段的唯一性,使用cascade={"persist"}会在体验复制时生成 sql 异常。

Sonata TripAdmin 类正确管理相同的模型,而不是尝试在 trip 持久添加新体验,而不是避免创建 ExperienceTrip 实体。在experience_trip表中,我可以正确看到正确的关联。

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

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

我自己找到了解决方案,也感谢此评论。

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

相关内容

最新更新