我有一个用户实体。在这种情况下,这被认为是主要实体,而仅用的事实就意味着它存在。
用户实体,具有商店实体。但是并非所有用户都一定都有商店实体。
值得注意的是,这是我们正在使用的现有数据库,用户表的ID与商店表的ID相同。名称(ID)和值。只是在某些情况下,商店没有给定用户ID的记录。
用户:
class User extends Entity
{
/**
* @ORMId
* @ORMColumn(type="string", length=36)
*/
protected $id;
/**
* @ORMOneToOne(targetEntity="Store")
* @ORMJoinColumn(name="id", referencedColumnName="id")
*/
protected $store;
...
}
商店:
class Store extends Entity
{
/**
* @ORMId
* @ORMColumn(type="string", length=36)
*/
protected $id;
...
}
这会导致控制器中的问题。如果用户实体没有商店记录,则它将失败,而"未找到实体"异常。可以使用试图捕获很容易处理(我找不到一种方法来检查实体对象是否存在还是只是代理)。如果用户 do 有一个商店记录,则一切都很好。
,但我尤其是固定装置:
protected function createUser($id)
{
$user = new User();
$user->setId($id);
$user->setEmail($id.'@example.com');
$user->setUserName($id.'_name');
$user->setArea($this->manager->find('Area', 156)); // Global
$this->manager->persist($user);
return $user;
}
当我运行固定装置时,这将失败。给我错误"违反完整性约束:1048列'ID'不能为null"。如果我从用户中删除商店实体,则此消息消失。因此,简而言之,如果没有商店,我将无法添加用户。
有人知道发生了什么事吗?我已经环顾四周,我找不到任何东西,包括学说文档,在实体之间有可选的关系。我认为这是一个普遍的情况。
在此文档页面上找到了解决方案:
http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#use-case-case-case-3-join-table-with-metadata
在我的情况下,而不是使用ID字段与商店实体关联的用户实体,而是用户(实体对象)与商店实体中的商店属性相关联。作为回报,商店对象将容纳用户实体,该实体被注释为实体的ID。
我敢肯定这就像地狱一样令人困惑,所以只看上面的样本。以下是我调整后的实体类:
用户
class User extends Entity
{
/**
* @ORMId
* @ORMColumn(type="string", length=36)
*/
protected $id;
/**
* @ORMOneToOne(targetEntity="Store", mappedBy="user")
*/
protected $store;
...
}
商店
class Store extends Entity
{
/**
* @ORMColumn(type="string", length=36)
*/
protected $id;
/**
* @ORMId
* @ORMOneToOne(targetEntity="User")
* @ORMJoinColumn(name="id", referencedColumnName="id")
*/
protected $user;
...
}
现在,如果没有给定用户的商店记录,则用户实体中的商店属性将为null。固定装置也按预期运行。
除了上面的答案外,我还需要添加inversedBy
属性。否则,将抛出无效的实体映射错误。
使用上面的实体,Store
对象需要看起来像:
class Store extends Entity
{
/**
* @ORMColumn(type="string", length=36)
*/
protected $id;
/**
* @ORMId
* @ORMOneToOne(targetEntity="User", inversedBy="store")
* @ORMJoinColumn(name="id", referencedColumnName="id")
*/
protected $user;
...
}