当我为此目的创建构造函数时,如何处理 Doctrine::find 未初始化未映射的实体属性?
Posted
技术标签:
【中文标题】当我为此目的创建构造函数时,如何处理 Doctrine::find 未初始化未映射的实体属性?【英文标题】:How can I deal with Doctrine::find not initializing unmapped entity properties when I have created a constructor for that purpose? 【发布时间】:2016-02-15 16:26:54 【问题描述】:我创建了一个 Doctrine 实体,将各种属性映射到数据库列,然后添加了我自己未映射到任何列的属性。然后我通过构造函数或在属性声明时初始化它们。
现在我遇到了一个问题,即 Doctrine fetch 使我的未映射属性未初始化:
class TheEntity
/**
* mapped to column
*
* @var integer @Column(name="num", type="integer", nullable=false)
*/
private $num;
/**
* unmapped var, being initialized at property declaration
* alternatively I can do it in a __construct() with the same result
*/
private $extraVar = '0.01';
//initializes my non-column mapped properties
//but does not load a record from the database
$object = new TheEntity();
//loads mapped properties but leaves unmapped one uninitialized
$object = $em->getRepository()->find($id);
我最终得到了一个部分加载的对象。
我的解决方案可能是将我未映射的属性添加到数据库中,并将属性映射到列。但我认为这是不可取的。我可以做到,但这涉及修改数据库。我宁愿寻求使用纯代码的解决方案。
如果可以避免的话,我也想避免像$entity->initializeUnmappedProperties()
这样的黑客攻击,并首先寻求涉及语言设施或 Doctrine 设施的解决方案。
尽管我在上面说过,理想情况下我正在为我寻找一个整体上最好的解决方案,所以我会接受一个反映最佳可用解决方案的答案。
【问题讨论】:
【参考方案1】:我似乎取得了不错的成绩
$object = $em->getRepository()->find($id);
$object->__construct();
未映射属性的初始化被移至构造函数
【讨论】:
Dennis,这可能是你最好的选择,因为教义类映射不会在 find 上初始化构造函数。但是,我建议将此行为移至抽象存储库并让您的自定义存储库扩展它。这样您就可以调用$repo->findWithConstruction($id)
,它会调用您解决方案中的代码。
调用__construct与调用initializeUnmappedProperties基本相同。如果您真的需要这种功能,请查看生命周期事件:doctrine-orm.readthedocs.org/en/latest/reference/events.html。但从长远来看,完全没有未映射的属性会更好。
@Syx,谢谢。你能给我一个准系统的伪代码吗?或者更详细的解释?我很难概念化抽象和自定义存储库模式
@Dennis - 我已添加示例作为答案。【参考方案2】:
这是您请求的(未经测试的)伪代码。
/**
* @ORM\Entity(repositoryClass="MyRepository")
*/
class MyEntity
public function __construct()
$this->autoPopulatedProp = 'foo';
abstract class AbstractRepository extends \Doctrine\ORM\EntityRepository
public function findWithConstruction($id)
$entity = parent::find($id);
return $entity->__construct();
class MyRepository extends AbstractRepository
// Implementation
$this->getDoctrine()
->getRepository('MyBundle:MyRepository')
->findWithConstruction($id);
【讨论】:
您还可以使用setDefaultRepositoryClassName
http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/advanced-configuration.html#default-repository-optional 隐式重载所有存储库(不带注释)以上是关于当我为此目的创建构造函数时,如何处理 Doctrine::find 未初始化未映射的实体属性?的主要内容,如果未能解决你的问题,请参考以下文章