Doctrine @OneToMany 关系不 return 集合

Doctrine @OneToMany relation doesn't return Collection

我正在使用带有 Doctrine 2 的 Symfony 2.7。当使用 OneToMany 关系时,属性 保持为空。

上下文

我正在尝试创建一个过滤器,以便只有当前受雇于某个组织的员工才能看到与该组织相关的实体。 (我已经创建了一个过滤器,其中包含一个硬编码的组织,有效)。

我创建了 en Employee 实体,该实体具有与用户的 ManyToOne 关系、与组织的 ManyToOne 关系、joindate 和 leavedate。用户与 Employee 具有(反向)OneToMany 关系。当我调用 $user->getEmployees() 时,我没有得到任何结果。

预期结果

当调用 $user->getEmployees() 时,我希望获得当前存储在数据库中的三个 Employee 实体的集合以及我的 user_id.

实际结果

返回一个空集合,var_dump

的一部分
object(Doctrine\ORM\PersistentCollection)[83]
  private 'snapshot' => 
    array (size=0)
      empty
  private 'owner' => 
    object(AppBundle\Entity\User)[342]
      protected 'id' => int 1
      protected 'groups' => 
        object(Doctrine\ORM\PersistentCollection)[52]
          private 'snapshot' => 
            array (size=0)
              ...
          private 'owner' => 
            &object(AppBundle\Entity\User)[342]
          private 'association' => 
            array (size=19)
              ...
          private 'em' => 
            object(Doctrine\ORM\EntityManager)[282]
              ...
          private 'backRefFieldName' => null
          private 'typeClass' => 
            object(Doctrine\ORM\Mapping\ClassMetadata)[42]
              ...
          private 'isDirty' => boolean false
          private 'initialized' => boolean false
          private 'coll' => 
            object(Doctrine\Common\Collections\ArrayCollection)[41]
              ...
      protected 'employees' => 
        &object(Doctrine\ORM\PersistentCollection)[83]

其他信息

在 Doctrine @OneToMany 上搜索给我的人忘记了一些参数、参数等或打错了字。我和我的大学在我的代码中找不到其中之一。所以我有点卡住了。请帮助。

composer.json(部分):

"require" : {
    "php" : ">=5.3.9",
    "symfony/symfony" : "2.7.*",
    "doctrine/orm" : "~2.2,>=2.2.3,<2.5",
    "doctrine/dbal" : "<2.5",
    "doctrine/doctrine-bundle" : "~1.4",
    "symfony/assetic-bundle" : "~2.3",
    "symfony/swiftmailer-bundle" : "~2.3",
    "symfony/monolog-bundle" : "~2.4",
    "sensio/distribution-bundle" : "~4.0",
    "sensio/framework-extra-bundle" : "~3.0,>=3.0.2",
    "incenteev/composer-parameter-handler" : "~2.0",
    "friendsofsymfony/user-bundle" : "~2.0@dev",
    "stof/doctrine-extensions-bundle" : "^1.2",
    "sonata-project/admin-bundle" : "^2.3",
    "sonata-project/doctrine-orm-admin-bundle" : "^2.3",
    "sonata-project/translation-bundle" : "1.0.0",
    "doctrine/doctrine-fixtures-bundle" : "^2.3"
},

Configuration.php(这是过滤器的配置)

<?php

namespace AppBundle\Filter;

use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Annotations\Reader;
use Doctrine\Common\Collections\Criteria;
use AppBundle\Entity\Employee;

class Configurator
{
    protected $em;
    protected $tokenStorage;
    protected $reader;

    public function __construct(ObjectManager $em, TokenStorageInterface $tokenStorage, Reader $reader)
    {
        $this->em              = $em;
        $this->tokenStorage    = $tokenStorage;
        $this->reader          = $reader;
    }

    public function onKernelRequest()
    {
        if ($user = $this->getUser()) {
            $filter = $this->em->getFilters()->enable('organisation');

            $user_id = $user->getId();
            print "User id: $user_id<br />\n"; // Just to check I can get the user_id, that works

            $employeeCollection = $user->getEmployees();  // Get the Employees
            var_dump($employeeCollection); // Oeps, no result
            die(); // Let's just quit (for now)
            // To Do find out all the organisation id's
            // $filter->setParameter('organisation_ids', $organisation_ids);
        }
    }

    private function getUser()
    {
        $token = $this->tokenStorage->getToken();

        if (!$token) {
            return null;
        }

        $user = $token->getUser();

        if (!($user instanceof UserInterface)) {
            return null;
        }

        return $user;
    }
}

User.php

<?php
// src/AppBundle/Entity/User.php

namespace AppBundle\Entity;

use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Group")
     * @ORM\JoinTable(name="fos_user_group",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
     * )
     */
    protected $groups;

    /**
     * @var Collection
     * @ORM\OneToMany(targetEntity="AppBundle\Entity\Employee", mappedBy="user", cascade="persist")
     */
    protected $employees;



    public function __construct()
    {
        $this->employees = new \Doctrine\Common\Collections\ArrayCollection();
        parent::__construct();
    }


    public function prePersist($user)
    {
        parent::prePersist($user);
        $user->setEmplolyees($user->getEmployees());
    }

    public function preUpdate($user)
    {
        parent::preUpdate($user);
        $user->setEmplolyees($user->getEmployees());
    }

    /**
     * Add employees
     *
     * @param \AppBundle\Entity\User $employee
     * @return Organisation
     */
    public function addEmployee(\AppBundle\Entity\User $employee)
    {
        $employee->setOrganisation($this);
        $this->employees[] = $employee;

        return $this;
    }


    function setEmployees($employees)
    {
        foreach ($employees as $employee)
        {
            $this->addEmployee($employee);
        }
    }

    /**
     * Remove employee
     *
     * @param \AppBundle\Entity\User $employee
     */
    public function removeEmployee(\AppBundle\Entity\User $employee)
    {
        $this->employees->removeElement($employee);
    }

    /**
     * Get employees
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getEmployees()
    {
        return $this->employees;
    }
}

Employee.php

<?php
// src/AppBundle/Entity/User.php

namespace AppBundle\Entity;

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
// use Doctrine\ORM\EntityManager;
use Gedmo\Mapping\Annotation as Gedmo;
use AppBundle\Annotation as CRUD;

/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 * @Gedmo\SoftDeleteable(fieldName="deleted")
 * @Gedmo\Loggable
 */
class Employee {


    /**
     * @ORM\Id
     * @ORM\Column(type="guid")
     * @ORM\GeneratedValue(strategy="UUID")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\User", inversedBy="employees")
     */
    private $user;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Organisation", inversedBy="employees")
     */
    private $organisation;



    /**
     * @ORM\Column(type="date")
     */
    private $joindate;

    /**
     * @ORM\Column(type="date", nullable=true)
     */
    private $leavedate;

    /**
     * @ORM\Column(type="datetime")
     * @Gedmo\Timestampable(on="create")
     *
     */
    private $created;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     */
    private $deleted;




    public function __toString()
    {
       return $this->user . ' - ' . $this->organisation  . ' (' . print_r($this->getJoindate(),1);
    }

    /**
     * Set created
     *
     * @param \DateTime $created
     * @return Employee
     */
    public function setCreated($created)
    {
        $this->created = $created;

        return $this;
    }

    /**
     * Get created
     *
     * @return \DateTime
     */
    public function getCreated()
    {
        return $this->created;
    }

    /**
     * Set deleted
     *
     * @param \DateTime $deleted
     * @return Employee
     */
    public function setDeleted($deleted)
    {
        $this->deleted = $deleted;

        return $this;
    }

    /**
     * Get deleted
     *
     * @return \DateTime
     */
    public function getDeleted()
    {
        return $this->deleted;
    }

    /**
     * Get id
     *
     * @return guid
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set user
     *
     * @param \AppBundle\Entity\User $user
     * @return Employee
     */
    public function setUser(\AppBundle\Entity\User $user = null)
    {
        $this->user = $user;

        return $this;
    }

    /**
     * Get user
     *
     * @return \AppBundle\Entity\User
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * Set organisation
     *
     * @param \AppBundle\Entity\Organisation $organisation
     * @return Employee
     */
    public function setOrganisation(\AppBundle\Entity\Organisation $organisation = null)
    {
        $this->organisation = $organisation;

        return $this;
    }

    /**
     * Get organisation
     *
     * @return \AppBundle\Entity\Organisation
     */
    public function getOrganisation()
    {
        return $this->organisation;
    }

    /**
     * Set joindate
     *
     * @param \DateTime $joindate
     * @return Employee
     */
    public function setJoindate($joindate)
    {
        $this->joindate = $joindate;

        return $this;
    }

    /**
     * Get joindate
     *
     * @return \DateTime
     */
    public function getJoindate()
    {
        return $this->joindate;
    }

    /**
     * Set leavedate
     *
     * @param \DateTime $leavedate
     * @return Employee
     */
    public function setleavedate($leavedate)
    {
        $this->leavedate = $leavedate;

        return $this;
    }

    /**
     * Get leavedate
     *
     * @return \DateTime
     */
    public function getleavedate()
    {
        return $this->leavedate;
    }
}

我不确定是否是它导致了问题。但这肯定无济于事。在 User 你做:

public function addEmployee(\AppBundle\Entity\User $employee)
{
    $employee->setOrganisation($this);
    $this->employees[] = $employee;

    return $this;
}

应该是$employee->setUser($this);

还有一件事。你这样做:

function setEmployees($employees)
{
    foreach ($employees as $employee)
    {
        $this->addEmployee($employee);
    }
}

集合是使用 add 方法设置的,而不是 set 方法。所以你应该这样做:

function addEmployees($employees)
{
    foreach ($employees as $employee)
    {
        $this->addEmployee($employee);
    }
    return $this;
}

当我在做的时候

var_dump(sizeof($employeeCollection));

我得到了预期的结果 3。

经验教训:集合的迭代器是惰性的。用它做点什么去填满它。

例如:

    var_dump(sizeof($employeeCollection));
    var_dump($employeeCollection);

给出预期结果:

int 3

object(Doctrine\ORM\PersistentCollection)[85]
  private 'snapshot' => 
    array (size=3)
      0 => 
        object(AppBundle\Entity\Employee)[94]
          private 'id' => string '0426c0cc-b517-11e5-8f2e-080027434d34' (length=36)
          private 'user' => 
            object(AppBundle\Entity\User)[339]
              ...
          private 'organisation' => 
            object(Proxies\__CG__\AppBundle\Entity\Organisation)[129]
              ...
          private 'joindate' => 
            object(DateTime)[104]
              ...
          private 'leavedate' => null
          private 'created' => 
            object(DateTime)[96]
              ...
          private 'deleted' => null
      1 => 
        object(AppBundle\Entity\Employee)[127]
          private 'id' => string '74ca2b62-bac6-11e5-b9ab-080027434d34' (length=36)
          private 'user' => 
            object(AppBundle\Entity\User)[339]
              ...
          private 'organisation' => 
            object(Proxies\__CG__\AppBundle\Entity\Organisation)[122]
              ...
          private 'joindate' => 
            object(DateTime)[125]
              ...
          private 'leavedate' => null
          private 'created' => 
            object(DateTime)[126]
              ...
          private 'deleted' => null
      2 => 
        object(AppBundle\Entity\Employee)[119]
          private 'id' => string 'c1e45d7f-b53e-11e5-8f2e-080027434d34' (length=36)
          private 'user' => 
            object(AppBundle\Entity\User)[339]
              ...
          private 'organisation' => 
            object(Proxies\__CG__\AppBundle\Entity\Organisation)[118]
              ...
          private 'joindate' => 
            object(DateTime)[130]
              ...
          private 'leavedate' => null
          private 'created' => 
            object(DateTime)[124]
              ...
          private 'deleted' => null
  private 'owner' => 
    object(AppBundle\Entity\User)[339]
      protected 'id' => int 1