Doctrine ManyToMany关系问题

时间:2014-01-04 04:42:20

标签: doctrine-orm many-to-many entity-relationship

我正在尝试将Doctrine实体和关系添加到我现有的数据库架构中,但我遇到了一些问题。

我有4张桌子:

+-------------+  +-----------+  +-----------------+  +-------------------+
| customers   |  | acl_roles |  | acl_permissions |  | acl_customer_role |
---------------  -------------  -------------------  ---------------------
| customer_id |  | id        |  | role_id         |  | customer_id       |
+-------------+  | name      |  | resource_id     |  | acl_role_id       |
                 +------------  | flags           |  +--------------------
                                +------------------

在我的ACL中,客户可以拥有多个角色,每个角色都可以拥有许多权限。客户/角色的映射是通过acl_customer_role表完成的。

我目前正在解决使这种关系发挥作用的问题。这些是我的实体(为简洁起见,删除了一些标准注释):

class Customer {

   /**
    * @ORM\ManyToMany(targetEntity="AclRole", cascade="persist")
    * @ORM\JoinTable(name="acl_customer_role",
    *    joinColumns={@ORM\JoinColumn(name="acl_role_id", referencedColumnName="customer_id")}
    * )
    */
   protected $roles;

}

class AclRole {

    /**
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;

}

如您所见,在我的客户实体中,我正在定义$roles。这是一个ManyToMany关系,因为许多角色可以属于许多客户。我将连接表设置为acl_customer_role,并指定需要进行连接的列。但是,我收到以下错误:

PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'acl_customer_role.aclrole_id' in 'on clause'' in vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php:641

似乎Doctrine的查询试图加入'acl_customer_role.aclrole_id',这显然不存在。

如何正确指定关系?

更新

似乎Doctrine正在修改我的列名。当我指定acl_role_id Doctrine删除第一个下划线并假设列名为aclrole_id时(如上面问题中的错误消息所示)。但是,当我添加两个下划线(例如acl__role_id时,它会在其中留下所有下划线并提供几乎相同的错误,而不是现在它无法加入acl__role_id

我几乎不知所措..

1 个答案:

答案 0 :(得分:2)

我知道这个问题很老但是最近我遇到了同样的错误/问题,我找到了解决方案。

默认情况下,Doctrine使用DefaultNamingStrategy类来生成例如joinColumn,joinTableName,propertyToColumnName names:

...
public function joinColumnName($propertyName)
{
    return $propertyName . '_' . $this->referenceColumnName();
}

这就是您生成aclrole_id列的原因。

要改变这种行为,您所要做的就是在app / config.yml文件中将Doctrine2的命名策略更改为下划线:

doctrine:

    orm:
        # ...
        naming_strategy: doctrine.orm.naming_strategy.underscore

UnderscoreNamingStrategy上课

...
public function joinColumnName($propertyName)
{
    return $this->underscore($propertyName) . '_' . $this->referenceColumnName();
}

这将生成:acl_role_id

您还可以实施自定义命名策略:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/namingstrategy.html

注意:这是在2.3版本中引入的。