简体   繁体   English

与学说相关的实体返回所有字段值NULL

[英]Doctrine related entities return all fields values NULL

I am using Symfony 3.1.10 on a server with PHP 5.6.31 (with Zend OPcache 7.0.6-dev), Apache and MySQL (Ver 14.14 Distrib 5.6.37). 我在具有PHP 5.6.31(带有Zend OPcache 7.0.6-dev),Apache和MySQL(版本14.14 Distrib 5.6.37)的服务器上使用Symfony 3.1.10。

I have an Entity called Document with a related Entity called Worker 我有一个名为Document的实体,而一个与之相关的实体为Worker

The relationship have always worked untill today... Non when I retrive a document with a worker, all the worker field are null (except the ID). 直到今天,这种关系一直有效。。。非与工作人员检索文档时,所有工作人员字段均为空(ID除外)。

So if in my DB there is a worker with fields: id 4, name: John, age: 33 if I retrive a document with this worker relater and dump $document->getWorker() i return an objet Worker with id: 4, name: null, age: null. 因此,如果在我的数据库中有一个工作人员,其字段为:id 4,名称:John,年龄:33如果我使用此工作人员关联者检索文档并转储$ document-> getWorker(),我将返回一个ID为4,的对象工人名称:null,年龄:null。

The Document class 文档类

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity
* @ORM\Table(name="documents")
* @ORM\Entity(repositoryClass="AppBundle\Repository\DocumentRepository")
*/
class Document
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", nullable=true)
     */
    protected $object;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Worker", cascade={"persist"}, inversedBy="documents")
     * @ORM\JoinColumn(name="worker_id", referencedColumnName="id", onDelete="SET NULL")
     */
    protected $worker;

    public function getId()
    {
        return $this->id;
    }

    public function setObject($object)
    {
        $this->object = $object;

        return $this;
    }

    public function getObject()
    {
        return $this->object;
    }

    public function setWorker(\AppBundle\Entity\Worker $worker = null)
    {
        $this->worker = $worker;

        return $this;
    }

    public function getWorker()
    {
        return $this->worker;
    }
}

The worker class 工人阶级

namespace AppBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints AS Assert;

/**
* @ORM\Entity
* @ORM\Table(name="workers")
* @ORM\Entity(repositoryClass="AppBundle\Repository\WorkerRepository")
*/
class Worker
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", nullable=true)
     * @Assert\NotBlank()
     */
    protected $firstName;

    /**
     * @ORM\Column(type="string", nullable=true)
     * @Assert\NotBlank()
     */
    protected $lastName;

    /**
     * @ORM\Column(type="string", nullable=true)
     * @Assert\NotBlank()
     */
    protected $age;

    /**
     * @ORM\OneToMany(targetEntity="AppBundle\Entity\Document", mappedBy="worker")
     */
    protected $documents;

    public function __construct()
    {
        $this->documents = new ArrayCollection();
    }

    public function __toString() {
        return $this->firstName . ' ' . $this->lastName;
    }

    public function getId()
    {
        return $this->id;
    }

    public function setFirstName($firstName)
    {
        $this->firstName = $firstName;

        return $this;
    }

    public function getFirstName()
    {
        return $this->firstName;
    }

    public function setLastName($lastName)
    {
        $this->lastName = $lastName;

        return $this;
    }

    public function getLastName()
    {
        return $this->lastName;
    }

    public function setAge($age)
    {
        $this->age = $age;

        return $this;
    }

    public function getAge()
    {
        return $this->age;
    }

    public function addDocument(\AppBundle\Entity\Document $document)
    {
        $this->documents[] = $document;

        return $this;
    }

    public function removeDocument(\AppBundle\Entity\Document $document)
    {
        $this->documents->removeElement($document);
    }

    public function getDocuments()
    {
        return $this->documents;
    }
}

I read here: Doctrine always return null values in production 我在这里阅读: 主义总是在生产中返回空值

I tried everything, but nothing works. 我尝试了一切,但没有任何效果。

This really looks like a lazy loading problem : See, when you query for a document since your query doesn't explicitly ask for the worker, it is not loaded. 这确实看起来像一个懒惰的加载问题:看,当您查询文档时,因为您的查询没有明确要求工人,所以它不会被加载。 The reference is loaded. 引用已加载。

And here, you never call for worker this is why you get Worker {#701 ▼ +__isInitialized__: false 在这里,您从不要求工作人员,这就是为什么您获得工作人员{#701 ▼ +__isInitialized__: false

First have you tried calling $document->getWorker() outside of dump() ? 首先,您是否尝试过在dump()之外调用$document->getWorker() dump() dump won't fetch nested collection to avoid overwhelm memory. 转储将不会获取嵌套的集合,以免占用过多的内存。 It should work in twig or even in a basic echo. 它应该在树枝上或什至在基本回波中都起作用。 echo $document->getWorker()->getFirstName()

When you get worker, use symfony debugger to see that you threw two queries, one to get the document and another one to get the worker. 当您获得工作程序时,请使用symfony调试器查看是否引发了两个查询,一个查询获取文档,另一个查询获取工作程序。 You should avoid this. 您应该避免这种情况。 This is called lazy loading. 这称为延迟加载。 You never asked for worker but doctrine is a pretty fine ORM and it is smart enough to load it by itself. 您从未要求过工人,但是该学说是一个很好的ORM,它足够聪明,可以单独加载它。

It is not that problematic when you work with one entity, but think about the extra db work when you will be fetching a list of documents. 当您使用一个实体时,这不是问题,但是当您要获取文档列表时,请考虑一下额外的数据库工作。

One better way to do this would be to use a custom query in the repository. 一种更好的方法是在存储库中使用自定义查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM