我试图将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 {
/**
* @ORMManyToMany(targetEntity="AclRole", cascade="persist")
* @ORMJoinTable(name="acl_customer_role",
* joinColumns={@ORMJoinColumn(name="acl_role_id", referencedColumnName="customer_id")}
* )
*/
protected $roles;
}
class AclRole {
/**
* @ORMColumn(name="id", type="integer", nullable=false)
* @ORMId
* @ORMGeneratedValue(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
上联接之外。
我几乎不知所措。。
我知道这个问题很老了,但最近我遇到了同样的错误/问题,我找到了解决方案。
默认情况下,Doctrine使用DefaultNamingStrategy
类生成例如joinColumn、joinTableName、propertyToColumnName名称:
...
public function joinColumnName($propertyName)
{
return $propertyName . '_' . $this->referenceColumnName();
}
这就是为什么在您的案例中生成了aclrole_id
列。
要改变这种行为,您所要做的就是将Doctrine2的命名策略更改为在app/config.yml文件中下划线:
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版本中引入的。