OneToMany关联不与Doctrine一起存储

时间:2016-09-28 07:02:25

标签: php doctrine-orm doctrine

目前正在创建包含一个或多个订阅的成员。一切运作良好,输出就是我所期望的。

当订阅与指定的成员相关联并且我在类完成之前转储此对象时,它就会被正确处理。

代码:

/** @var Member $member */
foreach ($members as $member) {
    $subscription = new MemberSubscription();
    $subscription->setBillingDate(new DateTime('now'));
    $subscription->setMember($member);
    $subscription->setPaid(true);

    $this->em->persist($member);
    $this->em->persist($subscription);
    $this->em->flush();
}

此循环后的转储(代码段):

Member {#1649 ▼
  #id: 3577
  <...>
  #subscriptions: PersistentCollection {#1616 ▼
    -snapshot: array:1 [ …1]
    -owner: Member {#1649}
    -association: array:15 [ …15]
    -em: EntityManager {#1452 …10}
    -backRefFieldName: "member"
    -typeClass: ClassMetadata {#1601 …}
    -isDirty: false
    -initialized: false
    -coll: ArrayCollection {#1628 ▼
      -_elements: array:1 [▼
        0 => MemberSubscription {#1669 ▼
          #id: 67
          #member: Member {#1649}
          #billing_date: DateTime {#1668 ▶}
          #paid: true
        }
      ]
    }
  }
}

据我所知,一切进展顺利。对象不再脏了。每当函数完成,意味着我离开页面,对象就不再包含它的订阅。

在我在另一个页面上再次加载成员后,这是一个转储(片段):

array:26 [▼
  "id" => 3577
  <..>
  "paid" => PersistentCollection {#1569 ▼
    -snapshot: []
    -owner: Member {#1552 ▶}
    -association: array:15 [ …15]
    -em: EntityManager {#1396 …10}
    -backRefFieldName: "member"
    -typeClass: ClassMetadata {#1565 …}
    -isDirty: false
    -initialized: false
    -coll: ArrayCollection {#1573 ▼
      -_elements: []
    }
  }
]

我的实体;

会员

/**
 * @ORM\Entity(repositoryClass="Foo\Member\MemberRepository")
 * @ORM\Table(name="Foo_Member", options={"charset"="latin1","collate"="latin1_swedish_ci"})
 */
class Member
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     * @var int|null
     */
    protected $id;

    /**
     * @ORM\OneToMany(targetEntity="MemberSubscription", mappedBy="member")
     */
    protected $subscriptions;

    <..>

    /**
     * @return int|null
     */
    public function getId()
    {
        return $this->id;
    }

    <..>

    /**
     * @return mixed
     */
    public function getSubscriptions()
    {
        return $this->subscriptions;
    }

    /**
     * @param mixed $subscriptions
     */
    public function setSubscriptions($subscriptions)
    {
        $this->subscriptions = $subscriptions;

        return $this;
    }
}

MemberSubscription

/**
 * @ORM\Entity()
 * @ORM\Table(name="Foo_MemberSubscription", options={"charset"="latin1","collate"="latin1_swedish_ci"})
 */
class MemberSubscription
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     * @var int|null
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Member", inversedBy="subscriptions")
     */
    protected $member;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     * @var DateTime|null
     */
    protected $billing_date;

    /**
     * @ORM\Column(type="boolean", nullable=true)
     * @var bool
     */
    protected $paid;

    /**
     * @return int|null
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @param int|null $id
     */
    public function setId($id)
    {
        $this->id = $id;
    }

    /**
     * @return mixed
     */
    public function getMember()
    {
        return $this->member;
    }

    /**
     * @param mixed $member
     */
    public function setMember($member)
    {
        $this->member = $member;
    }

    /**
     * @return null|DateTime
     */
    public function getBillingDate()
    {
        return $this->billing_date;
    }

    /**
     * @param null|DateTime $billing_date
     */
    public function setBillingDate($billing_date)
    {
        $this->billing_date = $billing_date;
    }

    /**
     * @return boolean
     */
    public function isPaid()
    {
        return $this->paid;
    }

    /**
     * @param boolean $paid
     */
    public function setPaid($paid)
    {
        $this->paid = $paid;
    }
}

1 个答案:

答案 0 :(得分:1)

学说只会照顾你们关系的拥有方。另请参阅文档chapter 11: Association Updates: Owning Side and Inverse Side

因此,为了能够从您的Member实体获得订阅,您需要手动更新反面。这样做的最佳方式可能是这样的:

MemberSubscription内:

//...

/**
 * @param mixed $member
 */
public function setMember($member)
{
    $this->member = $member;
    $member->addSubscription($this);
}

//...

更新

您的订阅PersistentCollection将延迟加载。您可以在输出中看到集合未初始化:

-initialized: false

简单地转储集合不会加载元素。一旦您与懒惰加载PersistentCollection Doctrine进行交互,您将为您加载/初始化该集合,并将使用其Member元素填充它。

您也可以通过拨打initialize();手动执行此操作。之后,您将在再次转储变量时看到元素。