当我为此目的创建构造函数时,如何处理 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 未初始化未映射的实体属性?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理构造函数的失败?

R如何处理关闭数据库连接

合并发布者时如何处理错误?

复制控制函数中如何处理 C++ 数组成员?

如何处理多个页面或表单

构造准备好的语句时如何处理可选列