首页 > 解决方案 > 一个非常简单的 OneToOne 加入请求的教义错误

问题描述

使用 Symfony 和 Doctrine,我有一个不起作用的加入请求 (OneToOne)。我不明白,因为我习惯于提出相同的请求并且它可以工作......我一定犯了一个明显的大错误,但我找不到它。

询问 :

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()
    ;
}

返回此错误:

尽管预期有一行或没有,但找到了多个查询结果。

我检查得很好。当我提供uuid并且name我在数据库中只有一个条目时。我在 PHPMyadmin 中复制了可运行的查询,我只有一行。

看起来 addSelect(userMedia, media) 试图返回两行而不是水合的一行(媒体必须在 userMedia.media 中)

UserMedia实体 :

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实体 :

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)
}

标签: symfonydoctrine

解决方案


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()
        ;
    }

这应该工作


推荐阅读