Search code examples
phpsymfonydoctrine-ormsymfony4

Symfony doctrine lazy load properties


I have an entity that stores large files as blobs to the DB.

I would now like to get Symfony to never ever load these blobs unless I specifically request them via the appropriate getter.

In essence I want the same idea as lazy-loading relationships but for a string property.

What I have tried so far is to put all my other properties that hold the file meta data into a trait and then apply that trait to two entities.

namespace App\Entity\Traits;

use Doctrine\ORM\Mapping as ORM;

trait DocumentMetaData
{
    /**
     * @var int|null
     *
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var \DateTime|null
     *
     * @ORM\Column(type="datetime")
     */
    private $date_uploaded;
}

One entity has nothing to it but the trait...

namespace App\Entity;

use App\Entity\Traits\DocumentMetaData;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table(name="documents")
 * @ORM\Entity()
 */
class Document
{
    use DocumentMetaData;
}

...the other has the added blob property:

namespace App\Entity;

use App\Entity\Traits\DocumentMetaData;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table(name="documents")
 * @ORM\Entity()
 */
class DocumentFile
{
    use DocumentMetaData;

    /**
     * @var string|null
     *
     * @ORM\Column(type="blob")
     */
    private $blob;
}

Now, if I don't want the blob to be loaded, for example for a listing of files, I simply use the entity that doesn't have the blob.

This approach sort of works but causes issues as I need to point both entities at the same table (see the class level ORM annotations).

Specifically, it makes doctrine freak out when running migrations:

The table with name 'myapp.documents' already exists.

That makes perfect sense and really I'm hoping that someone can point me to a nicer solution.

How can I tell doctrine not to load the blob unless its explicitly asked for?


Solution

  • So as per the comments on my question - the way to do this so that migrations do not break is to leverage doctrine's ability to lazy load relationships between tables.

    Basically I had to go and create a new entity that only holds my giant blobs and then establish a one to one relationship between the original entity and the blob entity.

    I then set that relationship to load EXTRA_LAZY and as a result I can now control when precisely the blobs of giant data should be loaded.

    I don't think this is ideal in terms of normalising the DB design but it works a lot better than anything else so happy with that.