Symfony2 DiscriminatorColumn作为外键并加载实体

时间:2015-05-11 23:54:46

标签: php entity-framework symfony orm doctrine-orm

我有InheritanceType SINGLE_TABLE,类型基于FK到另一个实体。

当我转到附件实体的详细信息页面时,它会加载产品实体。 但是当我尝试通过Item Attachmentcollection访问Product实体时,产品为NULL。

视图的控制器正在使用' $ entity = $ em-> getRepository(' projectTestBundle:Item') - > find($ id);' ' $ entity = $ em-> getRepository(' projectTestBundle:附件') - > 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 ▶}
    }

Attachment.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 个答案:

答案 0 :(得分:0)

我认为您的问题是您的附加实体中的产品实体是延迟加载的。为避免这种情况,您应该使用自定义方法查找您离开加入产品的实体,如下所示:

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

希望这有帮助