Symfony 2 与 Doctrine 中的一对多关系
Posted
技术标签:
【中文标题】Symfony 2 与 Doctrine 中的一对多关系【英文标题】:One-To-Many Relation in Symfony 2 with Doctrine 【发布时间】:2013-06-19 08:18:06 【问题描述】:我已经在 Stack Overflow 和网络上的其他地方查看了大量的问题/答案,但找不到解决这个问题的方法。
在我解释问题之前,我有:
剥离我的实体,使它们只有最少的属性和方法 已清除学说查询缓存/元数据缓存 删除并重新创建架构 检查了我的拼写我有以下两个实体:
<?php
namespace Docker\ApiBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Source
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="integer")
* @ORM\ManyToOne(targetEntity="Project",inversedBy="sources")
* @ORM\JoinColumn(referencedColumnName="id")
*/
private $project;
<?php
namespace Docker\ApiBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Project
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity="Source", mappedBy="project")
*/
private $sources;
public function __construct()
$this->sources = new ArrayCollection();
public function getSources()
return $this->sources;
所以许多“来源”可以属于一个“项目”。
在我的控制器中,我有:
$em = $this->getDoctrine()->getManager();
$project = $em->find('Docker\ApiBundle\Entity\Project', 1);
$sources = $project->getSources()->toArray();
我尝试了很多东西,但我总是得到:
Notice: Undefined index: project in /.../www/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php line 1577
就像我说的,我知道有很多关于这个问题的问题,但没有一个被接受的答案能解决我的问题。
这一切对于使用 Doctrine2 来说都是非常基础的,所以不确定我做错了什么——这可能是非常明显的事情。
任何帮助将不胜感激。
【问题讨论】:
$project var 不是 null 吗?或者在做时 ->getSources()->toArray();崩溃了? $project var 不为空,是的 - 当我在控制器中执行$sources = $project->getSources()->toArray();
时导致异常。如果我把它拿出来就可以了。
【参考方案1】:
你有:
/**
* @ORM\Column(type="integer")
* @ORM\ManyToOne(targetEntity="Project",inversedBy="sources")
* @ORM\JoinColumn(referencedColumnName="id")
*/
private $project;
删除:
@ORM\Column(type="integer")
来自注释。
【讨论】:
啊哈!这就对了。这也很有意义。谢谢。【参考方案2】:如果这正是您的代码,我在您的 Project 类中看不到命名空间。尝试添加命名空间行“命名空间 Docker\ApiBundle\Entity;”。 如果这是同一个文件夹,则不需要“使用”,但如果它是其他捆绑包或文件夹的一部分,请尝试输入“使用 Docker\ApiBundle\Entity\Project;”之类的行 在您的 Source 类中。我希望它有帮助..
否则:
<?php
namespace Azimut\ApiBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Source
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
private $name;
/**
* @ORM\Column(type="integer")
* @ORM\ManyToOne(targetEntity="Azimut\ApiBundle\Entity\Project", inversedBy="sources")
* @ORM\JoinColumn(onDelete="CASCADE")
*/
private $project;
/**
* Get id
*
* @return integer
*/
public function getId()
return $this->id;
/**
* Set project
*
* @param integer $project
* @return Source
*/
public function setProject($project)
$this->project = $project;
return $this;
/**
* Get project
*
* @return integer
*/
public function getProject()
return $this->project;
<?php
namespace Azimut\ApiBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity
*/
class Project
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity="Azimut\ApiBundle\Entity\Source", mappedBy="object", cascade="all")
*/
private $sources;
public function __construct()
$this->sources = new ArrayCollection();
public function getSources()
return $this->sources;
/**
* Get id
*
* @return integer
*/
public function getId()
return $this->id;
/**
* Add sources
*
* @param \Azimut\ApiBundle\Entity\Source $sources
* @return Project
*/
public function addSource(\Azimut\ApiBundle\Entity\Source $sources)
$this->sources[] = $sources;
return $this;
/**
* Remove sources
*
* @param \Azimut\ApiBundle\Entity\Source $sources
*/
public function removeSource(\Azimut\ApiBundle\Entity\Source $sources)
$this->sources->removeElement($sources);
和控制器的一小部分: 公共函数 helloAction()
$id = 1;
$em = $this->getDoctrine()->getManager();
$project = $em->getRepository('Azimut\ApiBundle\Entity\Project')->find($id);
$source1 = $em->getRepository('Azimut\ApiBundle\Entity\Source')->find(3);
$source2 = $em->getRepository('Azimut\ApiBundle\Entity\Source')->find(5);
$project->addSource($source1);
$sources = array();
$sources = $project->getSources();
var_dump($sources);
return ....
这对我来说很好用。
【讨论】:
好地方 - 但只是帖子的格式不完全存在。我已对其进行了更新,以便显示名称空间。 好的——太好了——对我有用。但是...我猜想像 Doctrine 这样的库的一些问题是 magic。它似乎为您做了很多,所以我想如果我已经用我的项目的源填充数据库,那么我不需要使用 addSource 将它们添加到项目实体中?我猜我可以做一些 postLoad 事件回调来自动执行此操作,但我不是 100% 确定(考虑到它所做的其他事情)为什么我需要这样做。事实上,我不知道为什么我什至需要首先设置注释? 感谢您为此付出的辛勤工作,但@zelkjo 的回答是正确的。在您的回复中,我必须将源添加到项目中,在 Zeljok 的项目中,如果数据库是预先填充的,那么它会返回我所期望的,即填充的源实体。我为你 +1 了 - 再次感谢。 这取决于你想做什么,我手动添加了一些来源和项目,因为我以前没有任何这样的实体。我以为您想将其保留为整数,并尝试使用尽可能多的代码。注释用于映射您数据库中的对象。您可以使用注释、yml 或 xml 来设置您的数据库。如果您对注释不够自信,请使用其他解决方案。以上是关于Symfony 2 与 Doctrine 中的一对多关系的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 SonataAdminBundle (Symfony) 管理 Doctrine ORM 类表继承?