好的,一句话:帮助!
有些事情我无法弄清楚。在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,所以在这里我给了注释驱动程序和我的实体的目录,当然还有数据库凭证。
答案 0 :(得分:2)
这是完全预期的行为,因为教义是延迟加载您的群组实体。这是因为你所做的就是:
$user->getGroup();
我将尝试解释为什么你只能在这里获得代理:
您已从数据库中解析的User
实体包含您的群组实体的标识符(在本例中为id = 1
)(此ID来自{{1}中的groupId
列表)。致电user
时,您只需为getGroup
实体创建代理,并将其Group
设置为id
。到目前为止,无需进行数据库交互。
由于您没有从1
实体请求任何其他内容,因此在这种简单的情况下,代理就足够了。一旦您从组实体请求另一个属性(任何其他直接属性(组表中的列)但标识符),您将注意到差异。例如,尝试在您的群组实体上调用Group
。此属性尚未加载,因此doctrine将从数据库中的getName()
表中获取id = 1
行,并将所有列作为属性(在这种情况下只有一个)加载到组对象中然后它将返回所请求名称的值。
所以试试这样:
group
你的输出会非常不同。
我希望这会使行为更容易理解。