我正试图通过Zend Framework 2进入Doctrine 2。 我有2个数据库表:
advertable
用户表
我现在有一个表单来添加新广告,并希望在我将广告保存在表格中时注入advert_user_id。我创建了2个实体:
/** Advert
*
* @ORM\Table(name="advert")
* @ORM\Entity(repositoryClass="Advert\Repository\AdvertRepository")
*/
class Advert
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var integer
*
* @ORM\Column(name="advert_user_id", type="integer", nullable=false)
*/
private $advertUserID;
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="adverts")
* @ORM\JoinColumn(name="advert_user_id", referencedColumnName="id")
*/
protected $user;
/**
* Set advertUserID
*
* @param integer $advertUserID
* @return Advert
*/
public function setAdvertUserID($advertUserID)
{
$this->advertUserID = (int) $advertUserID;
return $this;
}
/**
* Get advertUserID
*
* @return integer
*/
public function getAdvertUserID()
{
return $this->advertUserID;
}
/**
* Set user
*
* @param \Advert\Entity\User $user
* @return Advert
*/
public function setUser(\Advert\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* @return \Advert\Entity\User
*/
public function getUser()
{
return $this->user;
}
以下用户实体
/**
* User
*
* @ORM\Table(name="user")
* @ORM\Entity
*/
class User
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity="Advert", mappedBy="user")
*/
private $adverts;
在我的控制器中,我现在尝试执行以下操作:
if ($form->isValid())
{
$advert->setAdvertUserID('13'); //Static for testing
$this->getEntityManager()->persist($advert));
$this->getEntityManager()->flush();
不幸的是,数据库中的条目始终为null。如果我删除了我的广告实体中的@ORM \ ManyToOne $用户,它可以正常工作。该设置允许我通过广告实体读出用户名,那么为什么我不能在我的广告表中保存用户ID?
答案 0 :(得分:0)
首先,我建议不要明确地命名表和列(除非你有充分的理由)。您通常也不需要指定JoinColumn
s。让Doctrine处理这些事情,它会让生活变得更轻松。
接下来,您的实体应该为每个列或关系都有getter和setter。此外,User
实体应该有一个构造函数,它将$ adverts字段初始化为ArrayCollection
对象。 (Doctrine有一个用于实体方法生成的CLI命令;不知道它是如何与ZF集成的,在SF2中它是doctrine:generate:entities
)
现在,对于实际问题:您无法从user
对象访问advert
的原因是因为您从未设置过该关系。在您的setter中,您必须将实体或引用传递给该实体(google for $EM->getReference(…)
)。只有这样,Doctrine才能自动加载相关实体。
如果您只存储相关对象的ID,则每次都必须手动获取实体,因为Doctrine甚至不知道实体之间的关系。
答案 1 :(得分:0)
我知道您在会话中存储了user_id,并且您希望使用广告保存用户,而无需先从数据库中获取整个用户实体。 这听起来像是一个好主意,而且执行的查询较少。
这样做的方法是这样的:
首先从不必要的内容中清理您的广告实体,而不是根据Doctrine2规范$advertUserID
相关内容清理:)
/** Advert
*
* @ORM\Table(name="advert")
* @ORM\Entity(repositoryClass="Advert\Repository\AdvertRepository")
*/
class Advert
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="adverts")
* @ORM\JoinColumn(name="advert_user_id", referencedColumnName="id")
*/
protected $user;
/**
* Set user
*
* @param \Advert\Entity\User $user
* @return Advert
*/
public function setUser(\Advert\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* @return \Advert\Entity\User
*/
public function getUser()
{
return $this->user;
}
}
然后通过引用添加用户广告:
$user_id = 13
$entityManager = $this->getEntityManager();
// get User by reference (no queries executed)
$user = $entityManager->getReference('Advert\Entity\User' , $user_id);
// set the User in the Advert using the setUser method
$advert->setUser($user);
// Persist and flush!
$entityManager->persist($advert));
$entityManager->flush();
现在,您可以在广告表中找到user_id,并且没有执行其他查询来执行此操作。 阅读有关参考代理here in the Doctrine2 documentation的更多信息。