Gaylord.P
Gaylord.P

Reputation: 1468

Doctrine error on a very simple OneToOne join request

With Symfony and Doctrine, I have a join request that does not work (OneToOne). I don't understand because I'm used to making identical requests and it works ... I must have made a big visible error but I can't find it.

Query :

public function findByUuidAndName(string $uuid, string $name)
{
    return $this
        ->createQueryBuilder('userMedia')
        ->innerJoin('App:Media', 'media', 'WITH', '
            userMedia.media = media
        ')
        ->andWhere('media.uuid = :uuid')
        ->andWhere('media.name = :name')
        ->setParameter('uuid', $uuid)
        ->setParameter('name', $name)
        ->select('
            userMedia,
            media
        ')
        ->getQuery()
        ->getOneOrNullResult()
    ;
}

Return this error :

More than one result was found for query although one row or none was expected.

I checked well. When I provide uuid and name I only have one entry in the database. I copied runnable query in PHPMyadmin and I only have one line.

It looks like the addSelect(userMedia, media) is trying to return two lines instead of one hydrated (media must be in userMedia.media)

UserMedia entity :

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * UserMedia
 *
 * @ORM\Entity(repositoryClass="App\Repository\UserMediaRepository")
 * @ORM\HasLifecycleCallbacks()
 */
class UserMedia
{
    /**
     * @var integer
     *
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var Media
     *
     * @ORM\OneToOne(
     *     targetEntity="App\Entity\Media",
     *     cascade={"persist"},
     *     fetch="EAGER"
     * )
     */
    private $media;

    /**
     * @var \DateTime
     *
     * @ORM\Column(type="datetime")
     */
    private $createdAt;

    /**
     * @var User
     *
     * @ORM\ManyToOne(targetEntity="App\Entity\User")
     */
    private $createdBy;

    public function getMedia(): ?Media
    {
        return $this->media;
    }

    public function setMedia(?Media $media): void
    {
        $this->media = $media;
    }

    ... (setters & getters)
}

Media entity :

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;

/**
 * Media
 *
 * @ORM\Entity(repositoryClass="App\Repository\MediaRepository")
 */
class Media
{
    /**
     * @var integer
     *
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var File
     */
    private $file;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=36)
     */
    private $uuid;

    /**
     * @var string
     *
     * @ORM\Column(type="string")
     */
    private $name;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=8)
     */
    private $extension;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=15)
     */
    private $mime;

    /**
     * @var integer
     *
     * @ORM\Column(type="integer", options={"unsigned"=true})
     */
    private $size;

    ... (setters & getters)
}

Upvotes: 0

Views: 1363

Answers (1)

threeside
threeside

Reputation: 358

public function findByUuidAndName(string $uuid, string $name)
    {
        return $this
            ->createQueryBuilder('userMedia')
            ->leftJoin('userMedia.media', 'media')
            ->andWhere('media.uuid = :uuid')
            ->andWhere('media.name = :name')
            ->setParameter('uuid', $uuid)
            ->setParameter('name', $name)
            ->getQuery()
            ->getOneOrNullResult()
        ;
    }

This should work

Upvotes: 1

Related Questions