Doctrine 要求在 OneToMany 单向关联中使用 mappedBy

Doctrine requires mappedBy in a OneToMany unidirectional association

当我尝试在这两个实体之间建立 OneToMany 单向关联时,我在尝试更新数据库架构时遇到此错误:

$ app/console doctrine:schema:update --dump-sql

[Doctrine\ORM\Mapping\MappingException]
OneToMany mapping on field 'address' requires the 'mappedBy' attribute.

/**
 * User
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class User
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\OneToMany(targetEntity="Address")
     * @ORM\JoinTable(name="users_address",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="address_id", referencedColumnName="id", unique=true)}
     *      )
     */
    private $address;

    //...
}

/**
 * Address
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Address
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    // ...
}

如果关联是单向的,为什么需要 "mappedBy"? 提前致谢。

更新: 正如@tchap 的评论中提到的,单向 OneToMany 可以映射到 @ManyToMany 和连接列之一的唯一约束以强制执行 onetomany基数。正如文档所说,但这让我有点困惑,因为已经有一个 @OneToMay 注释。所以我只需要将上面的代码更改为此(只需将 @OneToMany 更改为 @ManyToMany):

/**
 * @ORM\ManyToMany(targetEntity="Address")
 * @ORM\JoinTable(name="users_address",
 *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="address_id", referencedColumnName="id", unique=true)}
 * )
 */
private $address;

A OneToMany 必须是双向的,并且始终是关系的反面,如果您定义反面,则需要使用 [=14= 指向关系的拥有方] 属性。拥有方是ManyToOne。在您的情况下,它看起来像这样:

User 中,您的关联有一个 mappedBy="user" 属性并指向拥有方 Address:

/** ONE-TO-MANY BIDIRECTIONAL, INVERSE SIDE
 * @var Collection
 * @ORM\OneToMany(targetEntity="Address", mappedBy="user")
 */
protected $addresses;

Address 中你的关联有一个 inversedBy="addresses" 属性并指向反面 User:

/** MANY-TO-ONE BIDIRECTIONAL, OWNING SIDE
 * @var User
 * @ORM\ManyToOne(targetEntity="User", inversedBy="addresses")
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 */
protected $user;

此解决方案的优点是您可以通过执行以下操作找到哪个用户拥有 Address$address->getUser(); 并且您跳过向数据库添加额外的连接 table。


如果您希望关系是单向的,您可以像更新中那样做;使用联接 table 定义 ManyToMany 关系,并在 address_id 列上添加唯一约束。

/**
 * @ORM\ManyToMany(targetEntity="Address")
 * @ORM\JoinTable(name="user_address",
 *     joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
 *     inverseJoinColumns={@ORM\JoinColumn(name="address_id", referencedColumnName="id", unique=true)}
 * )
 */

此解决方案的缺点是您无法从 Address 资源中找出哪个 User 拥有地址(Address 不知道 User ).这样的例子也可以在here in the Doctrine documentation chapter 5.6. One-To-Many, Unidirectional with Join Table.

中找到