0
votes

I have an InheritanceType of SINGLE_TABLE and the type is based on a FK to another Entity.

When I goto the detail page for the Attachment Entity it loads the Product Entity. But when I try to access the Product entity via the Item Attachmentcollection the product is NULL.

The controllers for the views are using '$entity = $em->getRepository('projectTestBundle:Item')->find($id);' '$entity = $em->getRepository('projectTestBundle:Attachment')->find($id);'

Dumps and files below.

Dump of Entity on Attachment Detail page

ImageAttachment {#361 ▼
  #product: Product {#390 ▼
    +__isInitialized__: false
    #id: "IMAGE"
    #name: null
     …4
  }
  -id: 1
  #name: "Test"
  #item: Item {#372 ▶}
}

Dump of Entity on item Detail Page via Collection

  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 is same class with simple text changes for now.)

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

1 Answers

0
votes

I think your problem is that your Product entity is lazy loaded, in your attachment entity. To avoid that, you should use a custom method to find your entity, where you left join your product, like this :

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

Hope this helps