Php 持久化一个实体并将其与另一个实体关联,而不会再次分散第二个实体
我正在用Durandal/Knockoutjs构建一个前端应用程序,用Symfony2构建一个web服务后端,我使用Doctrine访问数据库 我有两个实体,它们是一对多的关联,就像这样Php 持久化一个实体并将其与另一个实体关联,而不会再次分散第二个实体,php,json,symfony,doctrine-orm,Php,Json,Symfony,Doctrine Orm,我正在用Durandal/Knockoutjs构建一个前端应用程序,用Symfony2构建一个web服务后端,我使用Doctrine访问数据库 我有两个实体,它们是一对多的关联,就像这样 use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity * @ORM\Table(name = "drew_cat_door") */ class Door { public function __construct() {
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name = "drew_cat_door")
*/
class Door
{
public function __construct()
{
//$this->setAddTime(new \DateTime(date('Y-m-d H:i:s')));
if ($this->getAddTime() == null)
$this->setAddTime(new \DateTime(date('Y-m-d H:i:s')));
else
$this->setUpdateTime(new \DateTime(date('Y-m-d H:i:s')));
}
/**
* @ORM\Id
* @ORM\Column(type = "integer")
* @ORM\GeneratedValue(strategy = "AUTO")
*/
protected $id;
/**
* @ORM\Column(type = "string", length = 30)
*/
protected $name;
/**
* @ORM\ManyToOne(targetEntity = "DoorType", inversedBy = "doors")
* @ORM\JoinColumn(name = "type_id", referencedColumnName = "id")
*/
protected $type;
/**
* @ORM\Column(type = "string", length = 30, nullable = true)
*/
protected $filename;
/**
* @ORM\Column(type = "string", length = 100, nullable = true)
*/
protected $description;
/**
* @ORM\Column(type = "integer", nullable = true)
*/
protected $views;
/**
* @ORM\Column(type = "datetime")
*/
protected $add_time;
/**
* @ORM\Column(type = "datetime", nullable = true)
*/
protected $update_time;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return Door
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set filename
*
* @param string $filename
* @return Door
*/
public function setFilename($filename)
{
$this->filename = $filename;
return $this;
}
/**
* Get filename
*
* @return string
*/
public function getFilename()
{
return $this->filename;
}
/**
* Set description
*
* @param string $description
* @return Door
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set views
*
* @param integer $views
* @return Door
*/
public function setViews($views)
{
$this->views = $views;
return $this;
}
/**
* Get views
*
* @return integer
*/
public function getViews()
{
return $this->views;
}
/**
* Set add_time
*
* @param \DateTime $addTime
* @return Door
*/
public function setAddTime($addTime)
{
$this->add_time = $addTime;
return $this;
}
/**
* Get add_time
*
* @return \DateTime
*/
public function getAddTime()
{
return $this->add_time;
}
/**
* Set update_time
*
* @param \DateTime $updateTime
* @return Door
*/
public function setUpdateTime($updateTime)
{
$this->update_time = $updateTime;
return $this;
}
/**
* Get update_time
*
* @return \DateTime
*/
public function getUpdateTime()
{
return $this->update_time;
}
/**
* Set type
*
* @param \Drewkol\AdminBundle\Entity\DoorType $type
* @return Door
*/
public function setType(\Drewkol\AdminBundle\Entity\DoorType $type = null)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* @return \Drewkol\AdminBundle\Entity\DoorType
*/
public function getType()
{
return $this->type;
}
}
/**
* @ORM\Entity
* @ORM\Table(name = "drew_cat_doortype")
*/
class DoorType
{
public function __construct()
{
$this->doors = new ArrayCollection();
if ($this->getAddTime() == null)
$this->setAddTime(new \DateTime(date('Y-m-d H:i:s')));
else
$this->setUpdateTime(new \DateTime(date('Y-m-d H:i:s')));
}
/**
* @ORM\Id
* @ORM\Column(type = "integer")
* @ORM\GeneratedValue
*/
protected $id;
/**
* @ORM\Column(type = "string", length = 30)
*/
protected $name;
/**
* @ORM\OneToMany(targetEntity = "Door", mappedBy = "type")
*/
protected $doors;
/**
* @ORM\Column(type = "datetime")
*/
protected $add_time;
/**
* @ORM\Column(type = "datetime", nullable = true)
*/
protected $update_time;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return DoorType
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set add_time
*
* @param \DateTime $addTime
* @return DoorType
*/
public function setAddTime($addTime)
{
if ($addTime != null)
$this->add_time = $addTime;
return $this;
}
/**
* Get add_time
*
* @return \DateTime
*/
public function getAddTime()
{
return $this->add_time;
}
/**
* Set update_time
*
* @param \DateTime $updateTime
* @return DoorType
*/
public function setUpdateTime($updateTime)
{
$this->update_time = $updateTime;
return $this;
}
/**
* Get update_time
*
* @return \DateTime
*/
public function getUpdateTime()
{
return $this->update_time;
}
/**
* Add doors
*
* @param \Drewkol\AdminBundle\Entity\Door $doors
* @return DoorType
*/
public function addDoor(\Drewkol\AdminBundle\Entity\Door $doors)
{
$this->doors[] = $doors;
return $this;
}
/**
* Remove doors
*
* @param \Drewkol\AdminBundle\Entity\Door $doors
*/
public function removeDoor(\Drewkol\AdminBundle\Entity\Door $doors)
{
$this->doors->removeElement($doors);
}
/**
* Get doors
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getDoors()
{
return $this->doors;
}
}
很抱歉没有输入任何代码。正如您所看到的,门有一个门类型
很简单,在添加门时,我会发布一个JSON
{"name":"nowe","type":{"id":5,"name":"loluk","add_time":"2013-09-25T01:05:05+0200"},"description":"hehe\n","filename":"hehe.jpg"}
是一个完整的门实体模型,其类型已经存在。当我试图用此代码添加此实体时
$json_door = $this->get("request")->getContent();
if (empty($json_door))
return $this->createBadRequestException();
$door = $this->container->get("serializer")
->deserialize($json_door, "Drewkol\\AdminBundle\\Entity\\Door", "json");
$door->setAddTime(new \DateTime(date('Y-m-d H:i:s')));
$manager = $this->getDoctrine()->getManager();
$manager->persist($door);
$manager->flush();
我得到一个错误,上面写着
A new entity was found through the relationship 'Drewkol\AdminBundle\Entity\Door#type' that was not configured to cascade persist operations for entity: Drewkol\AdminBundle\Entity\DoorType@000000002d1b74500000000063b1c8fb. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'Drewkol\AdminBundle\Entity\DoorType#__toString()' to get a clue.
我的问题是:添加已添加类型的门的最干净和有效的方法是什么
如果要添加的实体中给定的类型已经存在于数据库中(之前必须添加),是否有任何方法可以告诉Doctrine尝试并解决该问题,或者我必须从JSON反序列化实体中获取并删除该类型以防止其持久化(使用建议的级联选项)然后用条令获取类型,然后将其设置为我的全新反序列化门实体的类型,这样条令就知道该类型了?我的意思是,我喜欢由knockoutjs生成并用JSON传输的数据模型,在我看来,这是一个普遍的缺点,无法按照我介绍的方式进行 我建议使用Doctrine
prePersist
事件来处理此问题。在prePersist
事件中,您需要编写一些逻辑来检查数据库,以确定doorType
是否存在
如果它存在,那么从数据库中获取doorType
,并使用它来代替取消序列化JSON时创建的doorType
对象
如果它不存在,请持久化从未序列化的敲除JSON创建的doorType
,然后持久化Door