我有一个用户实体。在这种情况下,这被认为是主要实体,仅仅使用它意味着它存在。
User实体具有Store实体。但并非所有用户都必须拥有商店实体。
值得注意的是,这是我们正在使用的现有数据库,User表的id与Store表的id相同。名称(id)和值。只是在某些情况下,Store没有给定用户ID的记录。
用户:
class User extends Entity
{
/**
* @ORM\Id
* @ORM\Column(type="string", length=36)
*/
protected $id;
/**
* @ORM\OneToOne(targetEntity="Store")
* @ORM\JoinColumn(name="id", referencedColumnName="id")
*/
protected $store;
...
}
商店:
class Store extends Entity
{
/**
* @ORM\Id
* @ORM\Column(type="string", length=36)
*/
protected $id;
...
}
这会导致控制器出现问题。如果用户实体没有商店记录,则会失败并且未找到"实体"例外。这可以使用try catch足够容易处理(我还没有找到一种方法来检查Entity对象是否存在或者只是一个代理)。如果用户确实有商店记录,那么一切都很好。
但我遇到的最大问题尤其是赛程:
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;
}
当我运行Fixtures时,这会失败。给我错误"完整性约束违规:1048栏' id'不能为空"。如果我从用户中删除商店实体,此消息将消失。简而言之,如果用户没有商店,我就无法添加用户。
任何人都知道发生了什么?我已经做了一些环顾四周,但我无法找到任何内容,包括学说文档,在实体之间建立可选关系。我认为这是一种常见的情况。
答案 0 :(得分:1)
在此doc页面上找到解决方案:
在我的情况下,用户实体不是使用id字段与Store实体相关联,而是User实体中的store属性将由用户(实体对象)与Store实体相关联。作为回报,Store对象将包含一个User实体,该实体被注释为实体的id。
我确信这就像地狱一样令人困惑,所以请看上面的示例。以下是我调整后的实体类:
用户
class User extends Entity
{
/**
* @ORM\Id
* @ORM\Column(type="string", length=36)
*/
protected $id;
/**
* @ORM\OneToOne(targetEntity="Store", mappedBy="user")
*/
protected $store;
...
}
存储
class Store extends Entity
{
/**
* @ORM\Column(type="string", length=36)
*/
protected $id;
/**
* @ORM\Id
* @ORM\OneToOne(targetEntity="User")
* @ORM\JoinColumn(name="id", referencedColumnName="id")
*/
protected $user;
...
}
现在,如果给定用户没有存储记录,则User实体中的store属性将为null。夹具也按预期运行。
答案 1 :(得分:0)
除了上面的答案,我还需要添加inversedBy
属性。否则,将抛出无效的实体映射错误。
使用上面的实体,Store
对象需要如下所示:
class Store extends Entity
{
/**
* @ORM\Column(type="string", length=36)
*/
protected $id;
/**
* @ORM\Id
* @ORM\OneToOne(targetEntity="User", inversedBy="store")
* @ORM\JoinColumn(name="id", referencedColumnName="id")
*/
protected $user;
...
}