【问题标题】:issues accessing related values in Symfony/Doctrine在 Symfony/Doctrine 中访问相关值的问题
【发布时间】:2018-10-18 16:10:17
【问题描述】:

我有一个状态表,用作在其他表示例中识别/标记状态的参考:

|  id   |   status   |
|-------|------------|
|  1    | Active     |
|  2    | Disabled   |
|  3    | Admin Only |
|  4    | Archived   |

我正在尝试在用户实体的 isEnabled() 函数中使用这些值。

 public function isEnabled() {

    $statusObj = $this->status;
    $statusValue = $statusObj->getStatus();

    if( $statusValue  != "Active" ){
        return false;
    }

    // Simply persisting true works
     return true;
}

使用此功能是否正在登录,我得到一个非对象错误。

错误:在非对象上调用成员函数 getStatus()

查看调试,$status 似乎是一个代理对象而不是我的状态对象,但似乎无法从这里找到任何指向正确方向的东西。

用户.orm.yml

AppBundle\Entity\User:
type: entity
table: user
indexes:
    fk_user_status1_idx:
        columns:
            - status_id
id:
    id:
        type: integer
        nullable: false
        options:
            unsigned: false
            comment: 'user Primary Key'
        id: true
        generator:
            strategy: IDENTITY
fields:
   # ....

manyToOne:
    status:
        targetEntity: Status
        cascade: {  }
        joinColumns:
            status_id:
                referencedColumnName: id
        orphanRemoval: false
manyToMany:
    roles:
        targetEntity: Role
        joinTable:
            name: user_has_role
            joinColumns:
                user_id:
                    referencedColumnName: id
            inverseJoinColumns:
                role_id:
                    referencedColumnName: id
lifecycleCallbacks: {  }

我尝试将 User.orm.yml 文件中的状态 fetch: 更改为 LAZY 和 EAGER 的值,但都没有改变任何东西。

我试图让这篇文章简洁,所以如果我遗漏了任何重要的细节,请告诉我。

***更新***

我没有根据Many To One - Unidirectional Relatioinship 设置映射/反转选项。我现在删除了“null”生成的值,因此状态与链接的文档相匹配。状态表和实体不以任何方式包含对用户的引用。

在我的 IDE 中运行调试时,我发现 isEnabled() 被调用了两次...... isEnabled() 的第一次调用看起来运行良好。 $statsObj 是 == 代理对象,当我调用 $statusObj->getStatus() 时,我看到它按预期返回“活动”。然后该函数返回 true,调试器第二次跳回 isEnabled()。 isEnabled() 的第二次运行我的用户对象为 NULL。经过数小时绞尽脑汁试图找出为什么 isEnabled() 运行两次之后……我终于想到,第一次运行是在登录时,第二次是在身份验证通过后重定向期间出现的。原来整个问题是 $this->status 从未添加到序列化/反序列化函数中,因此在反序列化之后状态属性为空,并且当调用 inEnabled 以验证它失败时。

解决方案与所描述的问题相去甚远,除非有人有任何建议可以使它对其他人有用,否则我将投票删除。

【问题讨论】:

  • 我现在没有时间获得完整的答案(抱歉),但乍一看,您似乎没有在您的 manytoone 上为 Status 设置 inversedBy。您还需要在 Status -> user 的 onetomany 关系上设置 mappedBy。这可能会有所帮助。还要检查 symfony 调试器在查询区域下显示的内容,它会显示错误配置的实体关系。
  • AppBundle\Entity\Status - 尝试在连接上使用 targetEntity 的完全限定名称

标签: php doctrine-orm doctrine symfony


【解决方案1】:

Doctrine 将您的关系包装在代理中,因为它们具有延迟加载机制。直接访问$this->status 时,您将获得该代理对象。

尝试使用 getter:

public function isEnabled() {
    if( $this->getStatus()->getStatus() != "Active" ){
        return false;
    }
    ...
}

这看起来有点好笑,但是$this->getStatus() 提供了状态实体,而附加的getStatus() 要求提供状态实体的“状态”字段。

【讨论】:

  • 明白,但我认为我的属性/实体命名在这里造成了一些混乱。我没有在上面的函数中调用 $this->getStatus() ,而是引用了私有变量 $this->status (这是 getStuats() 当然会返回的)。因此,设置 $status = $this->status 并调用 $status->getStauts() 在我看来与 $this->getStatus()->getStatus() 相同。两者都有效地 $this->status->getStatus() 在用户实体中。
【解决方案2】:

您尚未发布您的状态实体代码,但您可能需要进行如下更改:

manyToOne:
    status:
        targetEntity: Status
        cascade: {  }
        orphanRemoval: false
          inversedBy: value_in_Status
        joinColumn:
            name: status_id
            referencedColumnName: id

请注意,您使用的是“joinColumns”而不是“joinColumn”。

【讨论】:

  • YAML 主要是从现有的数据库模式生成的,这可以解释为什么 joinColumns 代替了 joinColumn。
猜你喜欢
  • 2011-06-20
  • 1970-01-01
  • 2017-07-27
  • 1970-01-01
  • 1970-01-01
  • 2014-08-16
  • 1970-01-01
  • 2011-04-02
  • 2012-03-23
相关资源
最近更新 更多