doctrine2 映射覆盖从 MappedSuperclass 继承的 inversedBy 字段。

问题描述 投票:8回答:3

另一个问题。我有一个抽象的BaseLog实体,它保存着与我的用户的关联.此外,我有2个实体(FooLog & BarLog),它们扩展了BaseLog。此外,我还有我的User Entity,它们应该持有两个关联到Log。一个是FooLog,一个是BarLog。这是我的问题。我收到错误信息是因为我不知道如何在扩展实体中覆盖BaseLog的 inversedBy字段。请你帮帮我。

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

BaseLog

/** @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;
}

我如何才能覆盖 基础日志's 倒置FooLog & 条形图.

我在这个设置上得到了几个Mapping错误:BaseLog。

  • BaseLog.BaseLog#user是指不存在的反面字段User#logs。 关联BaseLog#user指的是不存在的反面字段User#logs。
  • FooLog:关联的FooLog#用户指的是不存在的反面字段User#logs。 关联FooLog#用户指的是不存在的反面字段User#logs。
  • BarLog: 关联BarLog#用户指的是不存在的反面字段User#logs。 关联BarLog#user指的是不存在的反面字段User#logs。
  • 用户:关联BarLog#user指的是不存在的反面字段User#logs。 User#fooLogs和FooLog#user的映射是不一致的。
  • 用户:映射User#fooLogs和FooLog#user相互不一致。 User#barLogs和BarLog#用户的映射是不一致的.

请帮我整理一下映射。

symfony orm doctrine-orm mapping
3个回答
4
投票

我有类似的问题与单一继承。我通过在两个实体类(父类和继承类)中定义相同的关联,但名称不同来解决这个问题。在你的情况下,你可以尝试这样做。

    /** @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属性. 这可以消除学说验证错误。


3
投票

我也曾在使用 单表继承. 据我所知,并没有一个解决方案。虽然 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.

在这种情况下 CourseFacilitatorResponsibility 的一个子类(单表继承)。CourseResponsibility. CourseLocation 指的是多个 CourseResponsibility 实体。我认为单向关联是唯一的办法。


1
投票

IIRC在旧版本的Doctrine中没有很好的方法来覆盖映射。在Doctrine >= 2.2中,有一种叫做 联想 所以也许你可以使用它。

另外,为什么你不想把关联从基类移到具体类,然后定义有效的inverseBy呢?


0
投票

正确的方法是使用以下方法(从Doctrine 2.3开始)。AssociationOverrides.

移除 inversedBy="logs"BaseLog 类--因为一个映射的超级类无论如何都不代表一个真正的实体--然后在子类中覆盖它。下面是它的样子。

BaseLog

/** @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
}

name=@ORM\AssociationOverride 代表你想从映射的超级类中覆盖的字段。

© www.soinside.com 2019 - 2024. All rights reserved.