Symfony2 DiscriminatorColumn 作为外键并加载实体
Posted
技术标签:
【中文标题】Symfony2 DiscriminatorColumn 作为外键并加载实体【英文标题】:Symfony2 DiscriminatorColumn as Foreign Key and load Entity 【发布时间】:2015-05-11 23:54:46 【问题描述】:我有一个 InheritanceType
或 SINGLE_TABLE
,类型基于另一个实体的 FK。
当我转到附件实体的详细信息页面时,它会加载产品实体。 但是当我尝试通过 Item Attachmentcollection 访问 Product 实体时,产品为 NULL。
视图的控制器正在使用 '$entity = $em->getRepository('projectTestBundle:Item')->find($id);' '$entity = $em->getRepository('projectTestBundle:Attachment')->find($id);'
下面的转储和文件。
附件详细信息页面上的实体转储
ImageAttachment #361 ▼
#product: Product #390 ▼
+__isInitialized__: false
#id: "IMAGE"
#name: null
…4
-id: 1
#name: "Test"
#item: Item #372 ▶
通过集合在项目详细信息页面上转储实体
ImageAttachment #367 ▼
#product: null
-id: 1
#name: "Test"
#item: Item #323 ▶
附件.php
namespace project\TestBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Attachment
*
* @ORM\Table(name="attachments")
* @ORM\Entity
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="product", type="string")
* @ORM\DiscriminatorMap("IMAGE" = "project\TestBundle\Entity\ImageAttachment", "TEXT" = "project\TestBundle\Entity\TextAttachment")
* @ORM\Entity(repositoryClass="project\TestBundle\Entity\AttachmentRepository")
*/
class Attachment
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @ORM\ManyToOne(
* targetEntity="Item",
* inversedBy="attachments"
* )
* @ORM\JoinColumn(
* name="item_id",
* referencedColumnName="id",
* nullable=false
* )
*/
protected $item;
/**
* Get id
*
* @return integer
*/
public function getId()
return $this->id;
/**
* Set name
*
* @param string $name
* @return Attachment
*/
public function setName($name)
$this->name = $name;
return $this;
/**
* Get name
*
* @return string
*/
public function getName()
return $this->name;
/**
* Set item
*
* @param \project\TestBundle\Entity\Item $item
* @return Attachment
*/
public function setItem(\project\TestBundle\Entity\Item $item)
$this->item = $item;
return $this;
/**
* Get item
*
* @return \project\TestBundle\Entity\Item
*/
public function getItem()
return $this->item;
?>
ImageAttachment.php(TextAttachemnt 是同一个类,现在只是简单的文本更改。)
namespace project\TestBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Attachment
*
* @ORM\Entity
*/
class ImageAttachment extends Attachment
/**
* @ORM\ManyToOne(targetEntity="Product",cascade="persist",fetch="EXTRA_LAZY")
* @ORM\JoinColumn(name="product", referencedColumnName="product", nullable=true)
*/
protected $product;
/**
* Set product
*
* @param \project\TestBundle\Entity\Product $product
* @return ImageAttachment
*/
public function setProduct(\project\TestBundle\Entity\Product $product = null)
$this->product = $product;
return $this;
/**
* Get product
*
* @return \project\TestBundle\Entity\Product
*/
public function getProduct()
return $this->product;
/**
* Set item
*
* @param \project\TestBundle\Entity\Item $item
* @return ImageAttachment
*/
public function setItem(\project\TestBundle\Entity\Item $item)
$this->item = $item;
return $this;
/**
* Get item
*
* @return \project\TestBundle\Entity\Item
*/
public function getItem()
return $this->item;
Item.php
namespace project\TestBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Item
*
* @ORM\Table(name="items")
* @ORM\Entity
* @ORM\Entity(repositoryClass="project\TestBundle\Entity\ItemRepository")
*/
class Item
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @ORM\OneToMany(
* targetEntity="Attachment",
* mappedBy="item",
* cascade="persist", "remove",
* orphanRemoval=true
* )
*/
protected $attachments;
/**
* Get id
*
* @return integer
*/
public function getId()
return $this->id;
/**
* Constructor
*/
public function __construct()
$this->attachments = new \Doctrine\Common\Collections\ArrayCollection();
/**
* Set name
*
* @param string $name
* @return Item
*/
public function setName($name)
$this->name = $name;
return $this;
/**
* Get name
*
* @return string
*/
public function getName()
return $this->name;
/**
* Add attachments
*
* @param \project\TestBundle\Entity\Attachment $attachments
* @return Item
*/
public function addAttachment(\project\TestBundle\Entity\Attachment $attachments)
$this->attachments[] = $attachments;
$attachments->setItem($this);
return $this;
/**
* Remove attachments
*
* @param \project\TestBundle\Entity\Attachment $attachments
*/
public function removeAttachment(\project\TestBundle\Entity\Attachment $attachments)
$this->attachments->removeElement($attachments);
/**
* Get attachments
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getAttachments()
return $this->attachments;
【问题讨论】:
【参考方案1】:我认为您的问题是您的 Product 实体是延迟加载的,在您的附件实体中。为避免这种情况,您应该使用自定义方法来查找您的实体,您离开的位置加入您的产品,如下所示:
/* Controller*/
$entity = $em->getRepository('projectTestBundle:Item')->customFind($id);
/* ItemRepository */
$em = $this->getEntityManager();
$qb = $em->createQueryBuilder();
$qb
->select('Item','attachment')
->from('projetTestBundle\Entity\Item','Item')
->leftJoin('Project.attachment','attachment')
;
$q = $qb->getQuery();
return $q->getResult();
希望对你有帮助
【讨论】:
感谢您的示例,但这不起作用。附件类不知道 Product,因为附件类的 Product 是DiscriminatorColumn
。我想弄清楚如何使它能够用作 DiscriminatorColumn 和普通的 entityMap以上是关于Symfony2 DiscriminatorColumn 作为外键并加载实体的主要内容,如果未能解决你的问题,请参考以下文章