【问题标题】:Doctrine 2 self-referencing entity won't return the parent idDoctrine 2 自引用实体不会返回父 ID
【发布时间】:2011-03-18 15:23:55
【问题描述】:

我在这里按照手册设置了一个自引用实体:

http://www.google.com/url?sa=D&q=http://www.doctrine-project.org/docs/orm/2.0/en/reference/association-mapping.html%23one-to-many-self-referencing

我的课程是 Page(而不是 Category,就像在文档中一样)。在我的实体中 类我有一个我已经实现的 toArray() 方法,它将给出 我返回我的成员变量的值。对于那些领域 关联,然后我确保获取关联的类对象 抢身份证。我这样做是为了填充表格。这是来自的代码 我的 Page 实体中的 toArray() 方法以及我的 PageService 获取页面对象和调用的页面控制器代码的函数 toArray() 来填充我的表单。

http://pastie.org/1686419

正如我在代码 cmets 中所说,当调用 toArray() 方法时 页面控制器,所有值都会被填充,除了父 ID。 page_type 也是一个 ManyToOne 关联,它被填充 no 问题。从 Page 对象中显式获取父 id 在 toArray() 方法之外(在页面控制器中)确实返回 父 id 值。 (见代码。)

作为旁注,我在我的 Page 实体中使用 __get() 和 __set() 而不是完整的 getter/setter。

【问题讨论】:

  • 我刚刚发现,如果我直接实现 getId() getter 并在我的 toArray() 方法中使用它,它将返回 id 值。为什么,是个问题。为什么在 toArray() 方法(在我的控制器中)之外直接(没有完整的 getter)获取值?

标签: doctrine-orm


【解决方案1】:

我认为这是因为您被代理抓住了。当您在 Doctrine 2 中有关联时,相关对象不会直接作为对象返回,而是作为子类在调用方法之前不会填充其属性(因为延迟加载以保存数据库查询)。

由于您直接调用属性(使用 $this->parent->id)而不调用任何方法,因此对象属性全部为空。

此页面http://www.doctrine-project.org/docs/orm/2.0/en/tutorials/getting-started-xml-edition.html#a-first-prototype 在警告框中有关于此类事情的警告。尽管您的不是公共属性,但您访问的好像是因为该对象属于同一类并且正在发生相同的问题。

【讨论】:

  • 我正在使用 __get() 和 __set() 方法,它们允许您访问对象属性,就好像它们是公共的一样。我使用相同的方法从同一类的另一个关联(page_type)中检索 id,它工作正常。这个问题与这个特定的关联直接相关,我觉得它一定与它是对同一类型实体的引用有关。另外,正如我上面提到的,我可以在我的 toArray() 方法之外直接调用父 id 并且它可以工作。只有在 toArray() 方法中它不会检索值。
  • __get 和 __set 仅适用于不可访问的属性。因为它属于同一类,所以它们是可访问的,因此它只是直接访问私有属性。但是因为没有调用任何函数,所以还没有加载代理,所以所有的值都是空的。
  • 好的,我明白你现在在说什么了。但是,即使在我的 toArray() 方法中,这个问题也只会出现在这个值上。我可以毫无问题地直接在我的 toArray() 方法中访问 page_type id。 'page_type' => $this->page_type->id 据我所知,在我的 toArray() 调用之前没有任何其他代码可以加载带有 page_type 值的代理。
【解决方案2】:

不确定究竟是什么导致了您所描述的行为,但您可能最好让您的 toArray() 方法调用 getter/setter,而不是让 toArray() 直接对类属性进行操作。这将为您提供一致性,因此如果您为某些属性实现自定义 getter,您将始终从 toArray() 和 getter 获得相同的结果。

一个粗略的例子:

<?php
/** @Entity */
class MyEntity {

    // ....

    /** @Column */
    protected $foo;


    public function setFoo($val)
    {
        $this->foo = $val;
    }

    public function getFoo()
    {
        return 'hello ' . $this->foo;
    }

    public function toArray()
    {
        $fields = array('foo');
        $values = array();
        foreach($fields as $field) {
            $method = 'get' . ucfirst($field);
            if (is_callable(array($this, $method)) {
                $fields[$field] = $this->$method();
            } else {
                $fields[$field] = $this->$field;
            }
        }
        return $fields;
    }
}

现在你得到相同的结果:

<?php
$e = new MyEntity;
$e->setFoo('world');
$e->getFoo(); // returns 'hello world'
$e->toArray(); // returns array('foo' => 'hello world')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    • 2013-12-28
    • 2014-10-29
    相关资源
    最近更新 更多