【问题标题】:doctrine2 mapping overwrite inherited inversedBy field from MappedSuperclass学说 2 映射覆盖从 MappedSuperclass 继承的 inversedBy 字段
【发布时间】:2012-11-29 17:30:45
【问题描述】:

另一个问题。我有一个抽象的 BaseLog 实体,它保持与我的用户的关联。 此外,我有 2 个扩展 BaseLog 的实体(FooLog 和 BarLog)。此外,我有我的用户实体,假设它拥有两个与日志的关联。一个用于 FooLog,一个用于 BarLog。这是我的问题。我收到错误消息,因为我不知道如何在扩展实体时覆盖 BaseLog 的 inversedBy 字段。你能帮帮我吗?

因为我觉得我的解释不太好,这里是我的实体的设置。

基础日志

/** @ORM\MappedSuperclass */
abstract class BaseLog {
  /**
   * @ORM\ManyToOne(targetEntity="User", inversedBy="logs")
   * @ORM\JoinColumns({
   *   @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
   * })
   */
  private $user;
}

FooLog

/** @ORM\Entity */
class FooLog extends BaseLog {
  // Some additional fields
}

条形记录

/** @ORM\Entity */
class BarLog extends BaseLog {
  // Some additional fields
}

用户

/** @ORM\Entity */
class User {
  /**
   * @ORM\OneToMany(targetEntity="FooLog", mappedBy="user", cascade={"persist"})
   */
  private $fooLogs;

  /**
   * @ORM\OneToMany(targetEntity="BarLog", mappedBy="user", cascade={"persist"})
   */
  private $barLogs;
}

如何在 FooLogBarLog 中覆盖 BaseLoginversedBy

我在这个设置中遇到了几个映射错误: 基础日志

  • BaseLog:关联BaseLog#user是指不存在的反边字段User#logs。
  • FooLog:关联FooLog#user引用了不存在的反边字段User#logs。
  • BarLog:关联的BarLog#user指的是不存在的反边字段User#logs。
  • 用户:映射 User#fooLogs 和 FooLog#user 彼此不一致。
  • 用户:映射User#barLogs和BarLog#user彼此不一致。

请帮我整理一下地图。

【问题讨论】:

标签: symfony orm doctrine-orm mapping


【解决方案1】:

我在单继承方面遇到了类似的问题。我通过在两个实体类(父类和继承类)中定义相同的关联但名称不同来解决这个问题。在你的情况下,你可以试试这个:

    /** @ORM\Entity */
class FooLog extends BaseLog {
  /**
   * @ORM\ManyToOne(targetEntity="User", inversedBy="foologs")
   * @ORM\JoinColumns({
   *   @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
   * })
   */
   private $user;
}

在 BarLog 类中:

/** @ORM\Entity */
    class BarLog extends BaseLog {
      /**
       * @ORM\ManyToOne(targetEntity="User", inversedBy="barlogs")
       * @ORM\JoinColumns({
       *   @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
       * })
       */
       private $bar_user;
    }

注意不同的名称($bar_user)。 您还必须在用户实体中定义foologs 和barlogs 属性。这消除了学说验证错误。

【讨论】:

    【解决方案2】:

    我在使用 Single Table Inheritance 时遇到过同样的问题。据我所知,没有解决方案。尽管inversedBy 被认为是强制性的,但您似乎可以忽略它。但是,正如 Doctrine 文档所暗示的那样,性能会迅速恶化。

    @AssociationOverride 没有帮助,因为您不能修改关联定义,只能修改数据库列属性。

    我尝试了许多选项,但没有一个令人满意。

    更新:在运行app/console doctrine:schema:validate 时,我仍然无法找到解决此类错误的任何方法。

    [Mapping]  FAIL - The entity-class 'Acme\AcmeBundle\Entity\CourseLocation' mapping is invalid:
    * The field Acme\AcmeBundle\Entity\CourseLocation#facilitators is on the inverse side of a bi-directional relationship, but the specified mappedBy association on the target-entity Acme\AcmeBundle\Entity\CourseFacilitatorResponsibility#courseLocation does not contain the required 'inversedBy' attribute.
    

    在这种情况下,CourseFacilitatorResponsibilityCourseResponsibility 的子类(具有单表继承)。 CourseLocation 指的是多个 CourseResponsibility 实体。我认为单向关联是解决它的唯一方法。

    【讨论】:

    • 我也遇到了这个问题。现在有解决办法吗?
    【解决方案3】:

    IIRC 在旧版本的 Doctrine 中没有覆盖映射的好方法。在 Doctrine >= 2.2 中有一个叫做 association override 的东西,所以也许你可以使用它。

    顺便说一句,为什么您不想将关联从基类移动到具体类并定义有效的 inversedBy 呢?

    【讨论】:

    • 我想将关联保留在 BaseLog 中,因为除了 User 实体中的 var 名称之外,它每次都是相同的。
    • 我查看了提供的文档,但找不到如何覆盖 inversedBy 字段。还有其他建议吗?
    • 文档链接已失效。此外,使用“当前”而不是“最新”似乎是一个更明智的选择,因为它将指向实际发布的版本。新链接here
    【解决方案4】:

    执行此操作的正确方法(自 Doctrine 2.3 起)是使用 AssociationOverrides

    BaseLog 类中删除 inversedBy="logs" - 因为映射的超类无论如何都不代表真实实体 - 然后在子类中覆盖它。应该是这样的:

    基础日志

    /** @ORM\MappedSuperclass */
    abstract class BaseLog {
      /**
       * @ORM\ManyToOne(targetEntity="User")
       * @ORM\JoinColumns({
       *   @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
       * })
       */
      private $user;
    }
    

    FooLog

    /**
     * @ORM\Entity */
     * @ORM\AssociationOverrides({
     *     @ORM\AssociationOverride(name="user", inversedBy="fooLogs")
     * })
     */
    class FooLog extends BaseLog {
      // Some additional fields
    }
    

    条形记录

    /**
     * @ORM\Entity */
     * @ORM\AssociationOverrides({
     *     @ORM\AssociationOverride(name="user", inversedBy="barLogs")
     * })
     */
    class BarLog extends BaseLog {
      // Some additional fields
    }
    

    @ORM\AssociationOverride 中的name= 表示您要从映射的超类中覆盖的字段。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-12
      相关资源
      最近更新 更多