Skip to content
Advertisement

Doctrine ArrayCollection refuses to update after insert

I’m trying to save a collection of files.

When I save a collection, it goes into the DB without a hitch. Same with files. But when I add a collection and a new file in the same request (like here in the upload function). Whenever I then ask doctrine to get me the files in the collection (in this case the one new file). It always responds with an empty ArrayCollection. If I do a seperate get HTTP request and ask for the collection afterwards, it shows me the correct arrayCollection containing my one new file.

I have tried every way of persisting and flushing the entities, as well as changing cascade annotations, so far nothing has worked. I have tried clearing the doctrine cache as well.

The Annotations seem to be correct because calling a getCollection()->getFiles() results in an ArrayCollection containing the files linked to the collection. It just doesn’t seem to work right after creating both entities and linking them together.

Thank you very much for your help, code is down below.

This is my collection. Which contains files as an ArrayCollection.

/**
 * @Entity @Table(name="LH_FileCollections")
 **/
class LhFileCollection extends RootModel
{
    /**
     * @Column(type="string")
     */
    protected $title;

    /**
     * @OneToMany(targetEntity="LhFile", mappedBy="collection")
     */
    protected $files;

    //Getters and Setters

}

This is my File class.

/**
 * @Entity @Table(name="LH_Files")
 **/
class LhFile extends RootModel
{
    /**
     * @Column(type="string")
     */
    protected $name;

    /**
     * @Column(type="string")
     */
    protected $type;

    /**
     * @Column(name="file_hash", type="string")
     */
    protected $fileHash;

    /**
     * @ManyToOne(targetEntity="LhFileCollection", inversedBy="files", cascade={"persist"})
     * @JoinColumn(name="collection_id", referencedColumnName="id")
     */
    protected $collection; 

    //Getters and Setters
}

This is my save filecollection function.

/**
     * @return array|string
     * @throws DoctrineORMORMException
     * @throws DoctrineORMOptimisticLockException
     * @throws Exception
     */
    public function fileUpload(
        $title,
        $attachment = null,
        $allowedFileTypes = null,
        $maxAllowedFileSize = 5000000
    ) {

        //Create collection
        $collection = $this->fileCollectionRepository->add($title);

        foreach ($_FILES as $file) {
            if ($allowedFileTypes !== null) {
                $errors = $this->fileCheck($file, $allowedFileTypes, $maxAllowedFileSize);
                if (!empty($errors)) {
                    return $errors;
                }
            }
            $this->saveFile($file, $collection);
        }

        return $collection;
    }

This is my save file function.

    /**
     * @param $file
     * @param $collection
     * @return LhFile
     * @throws DoctrineORMORMException
     * @throws DoctrineORMOptimisticLockException
     */
    private function saveFile($file, $collection)
    {
        $currentDir = getcwd();
        $uploadDir = $currentDir . '/Data/Uploads/';
        $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
        $uniqueName = uniqid() . "_" . time() . '.' . $extension;

        move_uploaded_file($file['tmp_name'], $uploadDir . $uniqueName);

        $metaData = "...";

        $file = $this->fileRepository->add(
            $file['name'],
            $file['size'],
            $extension,
            $metaData,
            $uniqueName,
            $collection
        );

        return $file;
    }

And lastly the repository functions:

Filecollection:

/**
     * @param $fileCollection
     * @throws DoctrineORMORMException
     * @throws DoctrineORMOptimisticLockException
     */
    public function add($title)
    {
        $fileCollection = new LhFileCollection();

        $fileCollection->setTitle($title);
        $this->em->persist($fileCollection);
        $this->em->flush();

        return $fileCollection;
    }

And File

/**
     * @param $file
     * @throws DoctrineORMORMException
     * @throws DoctrineORMOptimisticLockException
     */
    public function add($name, $size, $type, $metaData, $uniqueName, $collection)
    {
        $file = new LhFile();

        $file->setName($name);
        $file->setSize($size);
        $file->setType($type);
        $file->setMetadata($metaData);
        $file->setFileHash($uniqueName);
        $file->setCollection($collection);
        $this->em->persist($file);
        $this->em->flush();

        return $file;
    }

Advertisement

Answer

It seems to me that in the current request from what I can make out that files are not being added to the collection->files array. The database is receiving the correct relationships which is why on the second request it is fine but the act of saving to the database doesn’t auto populate the relationships.

I think you need to explicitly add the file to the collection->files, assuming you have getFiles in LhFileCollection you could add after $this->saveFile($file, $collection);:

$collection->getFiles()->add($file);

There are of course a number of ways it can be done but ultimately you need to add the files to the collection->files.

Personally, I would build up the collection adding each file to the files array and only then save the collection. I wouldn’t persist and flush on every file because database actions could be expensive. You have cascade on so it should cascade to all files.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement