gpt4 book ai didi

php - 接收到的数据正确时,Doctrine2 hydration 不正确

转载 作者:行者123 更新时间:2023-12-03 11:20:48 27 4
gpt4 key购买 nike

编辑 2018-05-22:没有答案完全固定的问题 - 无法再复制问题,因为不再具有访问权限。不删除基于 this meta discussion

请不要花时间/精力来创建答案

@Wilt 的回答中的讨论使我了解了我现在对使用鉴别器的了解,这可能对 future 的提问者有所帮助。就我而言,它有所帮助,但没有提供答案。

我遇到了一些复杂的问题,即从客户端收到的数据 hydration 不正确。我已经尝试解决这个问题近一个星期了,所以我想问问你们。

我们有这个应用程序可以为学生创建作业。作业可能包含问题、文本项目、媒体项目等。问题在于问题和相关的答案。

场景

任务

  • 问题表 1 (L1)
  • 问题 1 (L1 - V1)
  • 答案 A (L1 - V1 - A1)
  • 答案 B (L1 - V1 - A2)
  • 问题 2(L1 - V2)
  • 答案 A (L1 - V2 - A1)(只有 1 个答案)
  • 问卷 2 (L2)
  • 问题 1(……等等)
  • 答案 A
  • 答案 B
  • 问题2
  • 答案 A
  • 答案 B
  • 问题 3
  • 答案 A
  • 答案 B

  • 以上内容从客户端正确发送。该数据的截图:

    Client side data

    需要注意的是,正如您在上面看到的, Question实际上是 GridElements实体。也可能是 TextImage ,这是基于属性 type = question这是一个 Discriminator .

    对数据进行 hydration 后,我们得到以下实体结构:

    Hydrated data

    如您所见, hydration 后数据不再正确。这是在 $form->isValid() 期间完成的. QuestionSheet 1包含第一个 QuestionQuestionSheet 2还有那个 Question有第一个 Answer来自第三个 Question第二个 QuestionSheet .

    在阅读完整的 hydration 数据集时,我看到 Answers为第一个 QuestionSheet 创建已被丢弃。 Answers来自第二个 QuestionSheet已被复制并覆盖了第一个问题表中的答案。本质上,您在上图中看到的内容。

    更糟

    下面是上面之后保存到数据库中的所有数据,上面提到了2个列表,5个问题和9个答案的场景。

    Database data

    所以第一个问题,没有问答了。第二个 QuestionSheet 的 Questions 已被用来覆盖它们。此外,只有最后 2 个答案在那里,填补了应该是 9! 的空间。

    顺便说一句,返回这个的查询完全是 LEFT JOIN为了也显示所有空数据,这就是剩下的全部。

    似乎它捕获了最后一组任何子实体来填充以前的实体,或者其他东西。我迷路了。

    这怎么可能?

    正如我所提到的,我已经研究了很长时间,但找不到解决方案。希望大家能帮忙。

    如果您需要有关代码的任何信息,我将尽我所能在此处显示它或在某些专有代码的情况下尽可能最好地解释它。

    更新 - 实体

    分配实体
    /**
    * @ORM\Entity(repositoryClass="Wms\Admin\Assignment\Repository\AssignmentRepository" )
    * @ORM\HasLifecycleCallbacks
    * @ORM\Table(name="ass_assignment")
    * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false)
    */
    class Assignment extends SeoUrl
    {
    //Traits and properties

    /**
    * @ORM\OneToMany(targetEntity="Wms\Admin\Assignment\Entity\QuestionSheet", mappedBy="assignment", cascade={"persist", "remove"}, orphanRemoval=true)
    **/
    protected $questionSheets;

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

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

    //More getters/setters
    }

    问题表实体
    /**
    * @ORM\Entity(repositoryClass="Wms\Admin\Assignment\Repository\QuestionSheetRepository")
    * @ORM\Table(name="ass_questionsheet")
    **/
    class QuestionSheet extends AbstractEntity
    {
    /**
    * @ORM\ManyToOne(targetEntity="Wms\Admin\Assignment\Entity\Assignment", inversedBy="questionSheets")
    * @ORM\JoinColumn(name="assignment_id", referencedColumnName="id", onDelete="CASCADE")
    **/
    protected $assignment;

    /**
    * @ORM\OneToOne(targetEntity="Wms\Admin\LayoutGrid\Entity\Grid", cascade={"persist", "remove"})
    * @ORM\JoinColumn(name="grid_id", referencedColumnName="id")
    **/
    protected $grid;

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

    //More getters/setters
    }

    网格实体
    /**
    * @ORM\Entity
    * @ORM\Table(name="lg_grid")
    **/
    class Grid extends AbstractEntity
    {
    /**
    * @ORM\OneToMany(targetEntity="Wms\Admin\LayoutGrid\Entity\Element\AbstractElement", mappedBy="grid", cascade={"persist", "remove"}, orphanRemoval=true)
    * @ORM\OrderBy({"y" = "ASC", "x" = "ASC"})
    */
    protected $gridElements;

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

    网格元素实体
    /**
    * @ORM\Table(name="lg_grid_element")
    * @ORM\Entity
    * @ORM\InheritanceType("JOINED")
    * @ORM\HasLifecycleCallbacks
    **/
    class AbstractElement extends AbstractEntity implements GridElementInterface
    {
    /**
    * @ORM\ManyToOne(targetEntity="Wms\Admin\LayoutGrid\Entity\Grid", inversedBy="gridElements")
    * @ORM\JoinColumn(name="grid_id", referencedColumnName="id", onDelete="CASCADE")
    **/
    protected $grid;

    public $type = ''; //This is a discriminator
    }

    问题实体
    /**
    * @ORM\Entity
    * @ORM\Table(name="lg_grid_question")
    **/
    class Question extends AbstractElement
    {
    /**
    * @ORM\OneToMany(targetEntity="Wms\Admin\LayoutGrid\Entity\Element\Answer", mappedBy="question", cascade={"persist"})
    */
    protected $answers;

    public $type = 'question'; //Inherited property, now filled in with discriminator value

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

    应答实体
    /**
    * @ORM\Entity
    * @ORM\Table(name="lg_grid_answer")
    **/
    class Answer extends AbstractEntity
    {
    /**
    * @ORM\ManyToOne(targetEntity="Wms\Admin\LayoutGrid\Entity\Element\Question", inversedBy="answers", cascade={"persist"})
    * @ORM\JoinColumn(name="question_id", referencedColumnName="id", onDelete="CASCADE")
    **/
    protected $question;

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

    更新 2
    更新 AbstractElement基于@Wilt 的回答的实体。
    /**
    * @ORM\Table(name="lg_grid_element")
    * @ORM\Entity
    * @ORM\InheritanceType("JOINED")
    * @ORM\HasLifecycleCallbacks

    * @ORM\DiscriminatorColumn(name="type", type="string")
    * @ORM\DiscriminatorMap({
    * "abstractElement"="AbstractElement",
    * "question"="Question",
    * //Others
    * })
    **/
    class AbstractElement extends AbstractEntity implements GridElementInterface
    {
    //Same as above
    }

    此更新为 NonUniformCollection 带来了一些问题它处理获取正确的实体。这曾经基于 $type属性(property)。

    但是,有一个 $type实体中具有 * @ORM\DiscriminatorColumn(name="type", type="string") 的属性作为符号,是不允许的。因此,所有使用鉴别器的类也已更新为以下内容。
    const ELEMENT_TYPE = 'question'; //Overwritten from AbstractElement

    /**
    * @return string
    */
    public function getType() //Overwritten from AbstractElement
    {
    return self::ELEMENT_TYPE;
    }

    唉,原来的问题依然存在。

    最佳答案

    我不确定这是否会导致您的问题,但在我看来,您的继承映射设置不正确:

    您需要在实体定义中声明鉴别器列 as written in the docs ,它们不应该被设置为属性,学说负责在你的数据库中设置它们:

    /**
    * @InheritanceType("JOINED")
    * @DiscriminatorColumn(name="type", type="string")
    * @DiscriminatorMap({"element"="AbstractElement", "question"="Question", "text"="TextItem", "media"="MediaItem"})
    */
    class AbstractElement extends AbstractEntity implements GridElementInterface
    {
    //...
    }

    您的抽象实体是否正确映射 as a @MappedSuperClass ?
    /**
    * @MappedSuperclass
    */
    class AbstractEntity
    {
    //...
    }

    这可能是您解决方案的一部分,请在相应更新后返回反馈...

    关于php - 接收到的数据正确时,Doctrine2 hydration 不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38993068/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com