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

时间:2012-12-12 03:57:25

标签: symfony orm doctrine-orm mapping

另一个问题。我有一个抽象的BaseLog实体,它保持与我的用户的关联。 另外,我有2个实体(FooLog& BarLog),它们扩展了BaseLog。另外我有我的用户实体,假设有两个与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
}

BarLog

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

如何在 FooLog &中覆盖 BaseLog inversedBy BarLog

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

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

请帮我把我的映射分类。

4 个答案:

答案 0 :(得分: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属性。这会删除学说验证错误。

答案 1 :(得分:3)

我使用Single Table Inheritance努力解决同样的问题。据我所知,没有解决方案。尽管inversedBy被认为是强制性的,但似乎你可以忽略它。然而,正如学说文件所表明的那样,表现迅速恶化。

@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个实体。我认为单向联想是绕过它的唯一方法。

答案 2 :(得分:1)

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

BTW为什么你不希望从基础到具体类的移动关联并定义有效的反转呢?

答案 3 :(得分:1)

自2000年以来,正确的方法是使用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
}

BarLog

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

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