I have Product entity and ProductAttachment entity. One product should be able to have many attachments. I Used Doctrine mapping OneToMnay – ManyToOne but everytime i get product, it has empty $files collection
ProductAttachment Entity
* @var ShopsysShopBundleModelProductProduct * @ORMManyToOne(targetEntity="ShopsysShopBundleModelProductProduct", inversedBy="files") * @ORMJoinColumn(nullable=false, name="product_id", referencedColumnName="id") */ public $product;
Product Entity
* @var ShopsysShopBundleModelProductProductAttachment[]|DoctrineCommonCollectionsArrayCollection * * @ORMOneToMany(targetEntity="ShopsysShopBundleModelProductProductAttachment", mappedBy="product", cascade={"persist"}) */ public $files; public function getFiles() { return $this->files; }
Am i Missing anything?
When i call
dump($product->getFiles());
this is what i get
DoctrineORMPersistentCollection #619d snapshot private => array () owner private => ShopsysShopBundleModelProductProduct #e2e7 association private => array (15) em private => DoctrineORMEntityManager #dfae backRefFieldName private => "product" (7) typeClass private => DoctrineORMMappingClassMetadata #5e75 isDirty private => false collection protected => DoctrineCommonCollectionsArrayCollection #57e3 | elements private => array () initialized protected => false
Advertisement
Answer
The problem is Doctrine’s lazy loading of collections, which is indicated on the PersistentCollection
object’s initialized
property – which is false
in your case. Meaning, it wasn’t initialized.
This is usually pretty smart, since you usually don’t need all of your entities relations loaded (and those related entities could have relations themselves etc.). Instead, the persistent collection will act as a proxy / wrapper and only load the collection contents once some part of the collection is actually accessed.
Some collection implementations have some interesting behavior, so I would advise to not expose collections to the “outside” of your entity. So my advice is to change the getFiles
to return $this->files->toArray()
and making the $files
property private
.
However, that’s just an advise. In any case, you calling toArray()
on any collection should initialize it and make it behave like the array you’d expect.