【发布时间】:2016-06-26 01:19:53
【问题描述】:
好的,一句话:帮助!
有些事情我想不通。在 ZF2 中,我使用了出色的 Doctrine Orm 模块。一切都很完美,但今天我发现了一些奇怪的东西。 我想我的某个地方一定有什么错误,但我找不到。或者也许在教义 2 中有一些我没有清楚理解的东西。
我已经映射了我的实体。当我有一个多对一关系而不指定 fetch 选项时,当我通过调用存储库上的 find() 方法获取一个实体时,我可以看到我的属性包含所生成的代理类的预期实例。但是当我在那个属性上调用 setter 时,它仍然包含代理类的 emtpy 实例???
Doctrine 似乎无法将实例链接到我的实体。就我而言,我从 find() 方法获得的实体是关系的所有者。
如果我在映射中指定 EAGER 上的 fetch 选项,则调用 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;
}
当然,我在这两个类中都有所有的 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 上的文档进行操作,所以在这里我给出了注释驱动程序和我的实体的目录,当然还有数据库凭据。
【问题讨论】:
-
这听起来像你错过了一些相当简单的东西,但如果没有更多细节就不可能说清楚。您可以通过显示一些代码来改进您的问题,尤其是相关的映射指令和您的存储库使用情况。
-
好的,我添加了一些细节:我创建了一个迷你项目以确保每件事都是干净的。我把我的实体的代码和我的测试。再一次,如果我将 fetch="EAGER" 放在用户实体中用于组关系,一切都很好。但没有它......
-
乍一看还不错。那么,接下来会发生什么? “调用该属性的 setter,然后它仍然包含代理类的 emtpy 实例”什么时候发生?
-
这就是 Doctrine 的运作方式。通过用代理类替换实体类,Doctrine 可以延迟查询和水合该关联的昂贵任务,直到它真正需要为止。 Doctrine 默认为 fetch
LAZY。但是,如果您使用选择EAGERfetch 选项,则返回实际的实体类。 Consider learning a little more about when to use it.
标签: doctrine-orm zend-framework2 lazy-loading