ZF2 项目中的 Doctrine 2 延迟加载问题

Doctrine 2 lazy loading issue in ZF2 project

好的,一言以蔽之:帮助!

有些事情我想不通。在 ZF2 中,我使用了很棒的 Doctrine Orm 模块。一切都很完美,但今天我发现了一些奇怪的事情。 我想我的某个地方一定有错误,但我找不到。又或者在 Doctrine 2 中有一些我没有理解清楚的地方。

我已经映射了我的实体。当我在没有指定获取选项的情况下建立多对一关系时,当我通过调用存储库上的 find() 方法获取一个实体时,我可以看到我的属性按预期包含代理 class 生成的实例.但是当我在该属性上调用 setter 时,它仍然包含代理的空实例 class ???

似乎 Doctrine 无法将实例链接到我的实体。在我的例子中,我从 find() 方法获得的实体是关系的所有者。

如果我在我的映射中指定了 EAGER 上的获取选项,那么调用 find() 方法 returns 一个实体,其属性按预期包含 class 中指定的实例关系。

有人遇到过同样的问题吗?

编辑: 好的,所以我创建了一个新的 ZF2 项目以确保没有任何干扰。 所以我有两个实体组和用户:

/**
 * Class Group
 * @package Application\Entity
 * @Entity
 * @Table("`group`")
 */
class Group
{
    /**
     * @Id
     * @GeneratedValue
     * @Column(type="integer", options={"unsigned"=true})
     */
    private $id;

    /**
     * @Column(type="string")
     */
    private $name;

    /**
     * @OneToMany(targetEntity="User", mappedBy="group")
     */
    private $users;
}

/**
 * Class User
 * @package Application\Entity
 * @Entity
 * @Table(name="user")
 */
class User
{
    /**
     * @Id
     * @GeneratedValue
     * @Column(type="integer", options={"unsigned"=true})
     */
    private $id;

    /**
     * @Column(type="string")
     */
    private $firstName;

    /**
     * @Column(type="string")
     */
    private $lastName;

    /**
     * @ManyToOne(targetEntity="Group", inversedBy="users")
     * @JoinColumn(name="groupId", referencedColumnName="id")
     */
    private $group;
}

当然,我在两个 class 中都有所有的 getter 和 setter,但我没有将它们放在示例中以加快速度。

在我的控制器中,我做了一件非常简单的事情来测试没有视图:

$user = $this->serviceLocator->get('doctrine.entitymanager.orm_default')->getRepository('Application\Entity\User')->find(1);
var_dump($user->getGroup());exit;

var_dump显示:

object(DoctrineORMModule\Proxy\__CG__\Application\Entity\Group)[367]
  public '__initializer__' => 
    object(Closure)[362]
  public '__cloner__' => 
    object(Closure)[363]
  public '__isInitialized__' => boolean false
  private 'id' (Application\Entity\Group) => int 1
  private 'name' (Application\Entity\Group) => null

当然,我在数据库中添加了用户和组,我在 table 组的一组中有一个 ID 为 1 的用户。

也许我错过了一个选项之类的?为了配置 Doctrine 模块,我只是按照 github 上的文档进行操作,所以在这里我给出了注释驱动程序和我的实体的目录,当然还有数据库凭证。

这完全是预料之中的行为,因为学说是延迟加载您的组实体。这是因为您所做的只是:

$user->getGroup();

我将尝试解释为什么您只能在这里获得代理:

您已经从数据库解析的 User 实体拥有您的组实体的标识符(在本例中为 id = 1)(此 ID 来自 groupIduser table)。当你调用 getGroup 时,学说只会为你的 Group 实体创建一个代理,并将其 id 设置为 1。到目前为止不需要数据库交互。

由于您没有向 Group 实体请求任何其他内容,因此在这种简单情况下代理就足够了。一旦您从您的组实体请求另一个 属性(任何其他直接 属性(您的组 table 中的列)但标识符),您会立即注意到差异。例如,尝试在您的群组实体上调用 getName()。此 属性 尚未加载,因此学说将从数据库中的 group table 中获取带有 id = 1 的行,并将所有列加载为属性(在本例中有只有一个)在您的组对象中,然后它将 return 所请求名称的值。

所以像这样尝试一次:

$user->getGroup()->getName();

而且你的输出会有很大的不同。

我希望这能让行为更容易理解。