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

Doctrine orm ZF2项目中的条令2延迟加载问题,doctrine-orm,zend-framework2,lazy-loading,Doctrine Orm,Zend Framework2,Lazy Loading,好的,一句话:救命 有件事我搞不懂。在ZF2中,我使用了出色的Orm模块。一切都很完美,但今天我发现了一些奇怪的事情。 我想一定是我在什么地方弄错了,但我找不到。或者在第二条原则中有一些我不太清楚的地方 我有我的实体映射。当我有一个多对一关系而没有指定fetch选项时,当我通过调用存储库上的find()方法获得一个实体时,我可以看到我的属性像预期的那样包含生成的代理类的实例。但是当我调用该属性的setter时,它仍然包含代理类的emtpy实例 看来条令无法将实例链接到我的实体。在我的例子中,我从

好的,一句话:救命

有件事我搞不懂。在ZF2中,我使用了出色的Orm模块。一切都很完美,但今天我发现了一些奇怪的事情。 我想一定是我在什么地方弄错了,但我找不到。或者在第二条原则中有一些我不太清楚的地方

我有我的实体映射。当我有一个多对一关系而没有指定fetch选项时,当我通过调用存储库上的find()方法获得一个实体时,我可以看到我的属性像预期的那样包含生成的代理类的实例。但是当我调用该属性的setter时,它仍然包含代理类的emtpy实例

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

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

有人有过同样的问题吗

编辑: 我创建了一个新的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;
}
当然,这两门课我都有所有的能手和二传手,但我并没有把他们放在例子中,以加快进度

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

$user = $this->serviceLocator->get('doctrine.entitymanager.orm_default')->getRepository('Application\Entity\User')->find(1);
var_dump($user->getGroup());exit;
变量转储显示:

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的用户


也许我错过了一个选择?要配置条令模块,我只需遵循github上的文档,因此这里我给出了注释驱动程序和实体目录,当然还有数据库凭据。

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

$user->getGroup();
我将尝试解释为什么您在此处仅获得代理:

您已经从数据库解析的
用户
实体包含您的组实体的标识符(在本例中为
id=1
)(此id来自
用户
表中的
组id
列)。调用
getGroup
时,条令仅为您的
Group
实体创建一个代理,并将其
id
设置为
1
。到目前为止,不需要数据库交互

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

所以试着这样做一次:

$user->getGroup()->getName();
您的输出将非常不同


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

这完全是预期的行为,因为条令是惰性加载组实体。这是因为你所做的就是:

$user->getGroup();
我将尝试解释为什么您在此处仅获得代理:

您已经从数据库解析的
用户
实体包含您的组实体的标识符(在本例中为
id=1
)(此id来自
用户
表中的
组id
列)。调用
getGroup
时,条令仅为您的
Group
实体创建一个代理,并将其
id
设置为
1
。到目前为止,不需要数据库交互

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

所以试着这样做一次:

$user->getGroup()->getName();
您的输出将非常不同


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

听起来你遗漏了一些相当简单的东西,但是如果没有更多的细节,就不可能说出来。您可以通过显示一些代码来改进您的问题,特别是相关的映射指令和您的存储库使用情况。我把我的实体代码和我的测试。再一次,如果我将fetch=“EAGER”放在组关系的用户实体中,一切都很好。但如果没有它…乍一看就很好。那么,接下来会发生什么?当doe“调用该属性上的setter时,它仍然包含代理类的emtpy实例”时,doe会发生这种情况吗?这就是Doctrine的工作原理。通过用代理类替换实体类,条令可以延迟查询和水合该关联的昂贵任务,直到实际需要为止。默认情况下,原则是fetch
LAZY
。但是,如果您使用了
EAGER
fetch选项,则返回实际的实体类。听起来好像你遗漏了一些相当简单的东西,但是如果没有更多的细节,就不可能说出来。您可以通过显示一些代码来改进您的问题,特别是相关的映射指令和您的存储库使用情况