Symfony3:关系一对多返回空对象

时间:2018-02-16 14:52:00

标签: php symfony doctrine-orm symfony-3.4

我正在尝试获取author实体中的One to Many Strip属性的内容。关系在AccountStrip实体之间,是双向的,并且由Strip实体拥有。

这是我的两个代码:

Strip.php

/**
* Strip
*
* @ORM\Table(name="strip")
* @ORM\Entity(repositoryClass="AppBundle\Repository\StripRepository")
*/
class Strip
{
//...
    /**
     *
     * @ORM\ManyToOne(targetEntity="Account", inversedBy="strips")
     * @ORM\JoinColumn(name="author_id", referencedColumnName="id")
     */
    private $author;
//...
}

Account.php

/**
 * Account
 *
 * @ORM\Table(name="account")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\AccountRepository")
 */
class Account
{
    //...
    /**
     * @var array
     *
     * @ORM\OneToMany(targetEntity="Strip", mappedBy="author")
     */
    private $strips;

    public function __construct() {
        $this->strips = new ArrayCollection();
    }
    //...
}

当我尝试从author获取strip属性时,我得到一个空的account,其右侧为id,但在其他字段上为空({{ 1}},username,...)。

例如,以下是slug返回的内容:

dump($strip->getAuthor())

以下是我的数据库的屏幕截图,显示此关系已正确注册:

Database screenshot strip table

Database screenshot account table

2 个答案:

答案 0 :(得分:3)

Doctrine2使用延迟加载。

  

每当您有一个托管实体实例时,您可以遍历并使用已配置为LAZY的该实体的任何关联,就好像它们已经在内存中一样。 Doctrine将通过延迟加载

的概念按需自动加载相关对象

嗨,这是Doctrine的懒惰......试着加入你的:

/**
 * @var array
 *
 * @ORM\OneToMany(targetEntity="Strip", mappedBy="author", fetch="EAGER")
 */
private $strips;

或更好的解决方案在StripRepository中创建自定义查询并选择作者

$this->createQueryBuilder('s')
     ->addSelect('a')
     ->join('s.author', 'a')

答案 1 :(得分:0)

我是如何解决这个问题的

我在StripRepository.php中执行了自定义加入查询,以获取AccountStrip个实体内容:

<强> StripRepository.php

class StripRepository extends \Doctrine\ORM\EntityRepository
{

    public function findAuthors($strip)
    {
        $query = $this->getEntityManager()
                ->createQuery(
                        'SELECT s, a 
                        FROM AppBundle:Strip s
                        JOIN s.author a
                        WHERE s.id = :id'
                )
                ->setParameter('id', $strip);

        try
        {
            return $query->getSingleResult();
        }
        catch (\Doctrine\ORM\NoResultException $e)
        {
            return null;
        }
    }

}

问题是什么?

Doctrine2默认使用延迟加载,因此这样做可以加载来自两个实体的所有内容,而不是仅加载来自Strip实体的内容。

我再次阅读Symfony文档关于Doctrine的关联,我找到了我使用的示例代码:

  

当然,如果您事先知道您需要访问这两个对象,则可以在原始查询中发出连接。

Joining Related Records - Symfony 3.4

感谢Mocrates让我领先:

  

或更好的解决方案在StripRepository中创建自定义查询并选择作者