Doctrine ODM返回基类代理对象而不是子类文档 [英] Doctrine ODM returns proxy object for base class instead of sub-classed document

查看:219
本文介绍了Doctrine ODM返回基类代理对象而不是子类文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我为我的项目提供新功能的工作期间,我决定扩展模型。我决定使用基类,分组常用的方法,几个子类,都保存在一个集合中。



基类,抽象类:

  / ** 
* @ MongoDB \Document(repositoryClass =EntryRepository)
* @ MongoDB \MappedSuperclass
* @ MongoDB \InheritanceType(SINGLE_COLLECTION)
* @ MongoDB \DiscriminatorField(fieldName =type)
* @ MongoDB \DiscriminatorMap({entry=Application_Model_Entry image=Application_Model_Image,movie=Application_Model_Movie})
* /
抽象类Application_Model_Entry
{
抽象函数foo();
}

一些具体的类(我有几个,类似,但有些是抽象):

 <?php 
/ ** @ MongoDB \Document * /
class Application_Model_Image extends Application_Model_Entry
{
function foo()
{
return'foo';
}
}

转换之后,我打开了我的索引页,提出了错误 - PHP正在尝试调用抽象方法,因为Doctrine返回的对象是 base 类的代理。我以为是因为我将这个集合从 Application_Model_Image 重命名为 Application_Model_Entry 和内部对象引用(仍然指向 Application_Model_Image 的$ ref 字段 DBRef ),但我注意到有趣的:始终第一个查询结果是一个具体类的正确文档,其余的是基类代理 - 在我从数据库中删除第一个对象后,第二个对象变得正常。



在单个对象显示页面上,所有对象都可以正常工作,所以我认为也许这是Zend Framework的寻呼机类迭代结果,所以我跳过了寻呼机并将对象倾倒直接从查询。我打印出100个第一个结果的类,其中一些有适当的课程(该贴上的列表的片段)。我查看了数据库,但是我没有注意到有关数据的任何事情(工作 vs 不工作)。我认为也许这是参考的错误,但正如我上面写的,同样的对象可能会变得工作,如果它是第一个结果列表。



任何想法或提示?我可以调试更多,但是我需要告诉在Doctrine的代码里面看看。

解决方案

已删除文档注释,一切都开始顺利进行。奇怪的结果,我曾经导致我在错误的地方找错误,但是幸运的是我在这里得到一个提示。



对于后代:




  • 文件注释是针对具体课程

  • MappedSuperclass 注释用于抽象类

  • 如果在查询结果中接收到代理类对象,那么可能在该部门中有一个混合

  • 即使没有文档注释,您也可以指示标识符字段/值。


During my work on providing new functionality to my project, I decided to expand models. I decided to use base class, grouping common methods, with few sub-classes, all kept in a single collection.

Base, abstract class:

/**
* @MongoDB\Document(repositoryClass="EntryRepository")
* @MongoDB\MappedSuperclass
* @MongoDB\InheritanceType("SINGLE_COLLECTION")
* @MongoDB\DiscriminatorField(fieldName="type")
* @MongoDB\DiscriminatorMap({"entry"="Application_Model_Entry", "image"="Application_Model_Image", "movie"="Application_Model_Movie"})
*/
abstract class Application_Model_Entry
{
    abstract function foo();
}

Some concrete class (I have few more of them, similar, but some are abstract):

<?php
/** @MongoDB\Document */
class Application_Model_Image extends Application_Model_Entry
{
    function foo()
    {
        return 'foo';
    }
}

After that transition, I opened my index page, and an error was presented - PHP was trying to call an abstract method, as the object returned by Doctrine was a proxy of the base class. I thought it was because I renamed the collection from Application_Model_Image to Application_Model_Entry and internal object references ($ref field of DBRef) were still pointing to Application_Model_Image, but I noticed something funny: always first query result was a proper document of a concrete class, and the rest were base class proxies - after I removed the first object from the database, the second one became fine.

On a single-object-showing page everything works fine, for all objects, so I thought maybe it's something with Zend Framework's pager class iterating over results, so I skipped the pager and dumped the objects directly from query. I printed out classes of 100 first results, and some of them had proper classes (Snippet of that list on pastebin). I looked into the DB, but I noticed nothing special about the data (working vs not working). I thought maybe it's something wrong with the references, but as I wrote above, the same object could become working if it was first on the result list.

Any ideas or hints? I can debug more, but I need to be told where to look inside Doctrine's code.

解决方案

Per comment by jmikola above, I've removed Document annotation, and everything started to work smoothly. The strange results I had led me to look for an error in a wrong place, but thankfully I got a tip here.

For posterity:

  • Document annotation is for concrete classes
  • MappedSuperclass annotation is for abstract classes
  • If you receive proxy class objects in query results, it's possible you have a mixup in that department
  • You can indicate discriminator field/values even without Document annotation.

这篇关于Doctrine ODM返回基类代理对象而不是子类文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆