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

时间:2016-06-24 21:07:14

标签: doctrine-orm zend-framework2 lazy-loading

好的,一句话:帮助!

有些事情我无法弄清楚。在ZF2中,我使用了精彩的Doctrine Orm模块。一切都很完美,但今天我发现了一些奇怪的东西。 我想我的某些地方肯定有一些错误,但我找不到。或者也许在Doctrine 2中有一些我不明白的东西。

我已经映射了我的实体。如果我没有指定fetch选项就有了Many To One关系,当我通过调用我的存储库中的find()方法获得一个实体时,我可以看到我的属性按预期包含生成的代理类的实例。但是当我在该属性上调用setter时,它仍然包含代理类的emtpy实例???

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

如果我在映射中指定了EAGER上的fetch选项,则调用find()方法返回一个实体,该实体的属性按预期包含关系中指定的类的实例。

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

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

/**
 * 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;
}

当然,我在这两个课程中都有所有的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

当然,我在数据库中添加了用户和组,并且我在表组中的一个组中有一个id为1的用户。

也许我错过了一个选项或什么?为了配置Doctrine模块,我只关注github上的doc,所以在这里我给了注释驱动程序和我的实体的目录,当然还有数据库凭证。

1 个答案:

答案 0 :(得分:2)

这是完全预期的行为,因为教义是延迟加载您的群组实体。这是因为你所做的就是:

$user->getGroup();

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

您已从数据库中解析的User实体包含您的群组实体的标识符(在本例中为id = 1)(此ID来自{{1}中的groupId列表)。致电user时,您只需为getGroup实体创建代理,并将其Group设置为id。到目前为止,无需进行数据库交互。

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

所以试试这样:

group

你的输出会非常不同。

我希望这会使行为更容易理解。