Doctrine - OneToMany关系,所有结果行都不在对象

时间:2018-01-08 14:46:00

标签: php symfony doctrine hydration

我尝试将所有对象DemandCab与其子对象(DecisionCab)。

我的2个实体

/**
 * DemandCab.
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="DemandCabRepository")
 */
class DemandCab
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
     private $id;

    /**
     * @var DecisionCab
     *
     * @ORM\OneToMany(targetEntity="\My\CabBundle\Entity\DecisionCab", mappedBy="demandCab")
     */
     private $decisionsCab;

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

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="endDate", type="datetime", nullable=true)
     */
     private $endDate;

    /**
     * @var int
     *
     * @ORM\Column(name="followup", type="integer", nullable=true)
     */
     private $followup;

    /**
     * @var InfoCab
     *
     * @ORM\ManyToOne(targetEntity="\My\CabBundle\Entity\InfoCab", inversedBy="demandsCab")
     */
     private $infoCab;

}

/**
 * DecisionCab.
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="DecisionCabRepository")
 */
 class DecisionCab
 {
     /**
      * @var int
      *
      * @ORM\Column(name="id", type="integer")
      * @ORM\Id
      * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

     /**
      * @var DemandCab
      *
      * @ORM\ManyToOne(targetEntity="\My\CabBundle\Entity\DemandCab", inversedBy="decisionsCab")
      */
     private $demandCab;

    /**
     * @var bool
     *
     * @ORM\Column(name="decision", type="boolean", nullable=true)
     */
     private $decision;

    /**
     * @var string
     *
     * @ORM\Column(name="motif", type="string", length=500, nullable=true)
     */
     private $motif;

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

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="date", type="datetime", nullable=true)
     */
     private $date;

    /**
     * @var DemandCab
     *
     * @ORM\ManyToOne(targetEntity="\My\CabBundle\Entity\DemandCab", inversedBy="decisionsCab")
     */
     private $demandCab;

    /**
     * @var User
     *
     * @ORM\ManyToOne(targetEntity="\My\CabBundle\Entity\User", inversedBy="decisionsCab")
     */
    private $user;
}

在我的DemandCabRepository

public function findAllCompleted(){
    $qb = $this->createQueryBuilder("dem");
    $qb->select('dem, dec');
    $qb->leftJoin("dem.decisionsCab", "dec");
    $qb->andWhere("dem.completed = 1");
    $qb->orderBy("dem.startDate", "DESC");

    return $qb->getQuery()->getResult();
}

我的DemandCab数据

My DemandCab data

我的DecisionCab数据

enter image description here

当我转储结果时,只有2个决定出现...... enter image description here

...当我使用getArrayResult时,我有4个决定...... enter image description here

查询很好,但我不明白为什么水化会删除带有属性decision的DecisionCab对象为0或1(仅显示null)。

我想了解为什么并且有一个解决方案来获取所有DecisionCab子对象的DemandCab对象。

由于

2 个答案:

答案 0 :(得分:1)

我能够重现您的问题,但我不确定这是否属于您的情况。

无论如何,我的假设是您在查询构建器的帮助下至少查询一次与决策关联的需求实体。也许这是在您的操作,事件监听器或代码中的其他位置完成的。

所以你可能有类似的东西:

$qb = $this->getDoctrine()
        ->getRepository(DemandCab::class)->createQueryBuilder("dem");
$qb->select('dem, dec');
$qb->leftJoin("dem.decisionsCab", "dec");

$qb->andWhere("dec.decision IS NULL");
$qb->orderBy("dem.startDate", "DESC");

$results = $qb->getQuery()->getResult(); // <-- the decisionsCab collection is hydrated but filtered

$qb2 = $this->getDoctrine()
        ->getRepository(DemandCab::class)->createQueryBuilder("dem");
$qb2->select('dem, dec');
$qb2->leftJoin("dem.decisionsCab", "dec");

$qb2->andWhere("dem.completed = 1");
$qb2->orderBy("dem.startDate", "DESC");

    $q = $qb2->getQuery();
    //$q->setHint(Query::HINT_REFRESH, true);

    $results = $q->getResult();

问题出在 Doctrine \ ORM \ Internal \ Hydration \ ObjectHydrator ,它有属性&#34; initializedCollections &#34;其中保留了已初始化的集合,并且父集合实体类型和实体本身对集合进行了散列。不幸的是,在上述情况下,heydrator不理解该集合在第一个查询中被过滤并在第二个查询中使用它以避免再水化。(github link

解决方案是使查询构建器刷新。试试代码:

$qb->orderBy("dem.startDate", "DESC");
$q = $qb->getQuery();
$q->setHint(Query::HINT_REFRESH, true);    // <-- Tell the hydrator to refresh
return $q->getResult();

答案 1 :(得分:0)

首先,您使用ManyToOne与ArrayCollection的关系初始化您的类。

你不需要任何这个'DemandCabRepository'。所有工作都由Doctrine

完成