教义多对多关系问题
Posted
技术标签:
【中文标题】教义多对多关系问题【英文标题】:Doctrine ManyToMany relationship issues 【发布时间】:2014-01-21 21:50:26 【问题描述】:我正在尝试将 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
。这是一个多对多关系,因为许多角色可以属于许多客户。我将连接表设置为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】:我知道这个问题很老,但最近我遇到了同样的错误/问题,我找到了解决方案。
默认情况下,Doctrine 使用DefaultNamingStrategy
类生成例如joinColumn、joinTableName、propertyToColumnName 名称:
...
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 版中引入的。
【讨论】:
以上是关于教义多对多关系问题的主要内容,如果未能解决你的问题,请参考以下文章