My use case is simple. There are two entities:
Server
andClient
. Each Server can have Multiple Clients. This should be pretty simple really...
我需要什么
因此,我需要以下内容:
- 调用
$server->getClients()
将返回所有Client
与该服务器关联的实体 - 调用
$client->getServer()
将返回Server
与该客户相关的实体
我相信,根据documentation ,这是一个一对多双向关系。
A one-to-many association has to be bidirectional, unless you are using an additional join-table. This is necessary, because of the foreign key in a one-to-many association being defined on the “many” side. Doctrine needs a many-to-one association that defines the mapping of this foreign key.
上面的文档给出了一个非常简单的 example的 Product
和 Feature
实体,我试图为我的 Server
采用这些实体至 Client
用例。
问题
首先,我似乎无法获得正确的注释来创建 Client
实体,将其分配给新创建的 Server
实体,然后坚持/保存它们。 Client
实体总是有 null
对于 server_id
属性。需要什么顺序?为什么我的注释不起作用?
其次,我不知道是否需要连接表才能执行 $client->getServer()
或者反过来:$server->getClients()
. 我是否需要一个连接表来满足上述条件?我尝试添加一个连接表,但在运行 doctrine orm:schema-tool:update
时实际上没有创建连接表。 .
代码
注意:我在 Client
的两端都有 Setters/Getters和 Server
/**
* Class Server
*
* @ORM\Table(name="servers")
* @ORM\Entity(repositoryClass="App\Model\Repository\ServerRepository")
*/
class Server
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var ArrayCollection
*
* @ORM\OneToMany(targetEntity="App\Model\Entity\Client", mappedBy="server", cascade={"persist", "remove"})
*/
private $clients;
}
/**
* Class Client
*
* @ORM\Table(name="clients")
* @ORM\Entity(repositoryClass="App\Model\Repository\ClientRepository")
*/
class Client
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var Server
*
* @ORM\OneToMany(targetEntity="App\Model\Entity\Server", inversedBy="client")
* @ORM\JoinColumn(name="server_id", referencedColumnName="id")
*/
private $server;
}
我尝试了多种创建 Client
的组合和 Server
实体,调用 $server->addClient(new Client));
等等,坚持不同的顺序等等。
我到底做错了什么?为什么我有 null
?为了实现方法 ::getClients()
,我需要什么来修复我的注释和对象持久性?和 ::getServer()
是否可供我使用?
最佳答案
您需要确保突变器(getter 和 setter)方法存在(afaik,至少在我的学说版本中)getter setter 不是由学说生成的,您需要实现它们。并且数组集合必须在构造函数中:
在 Server
实体中:
public function __construct() {
$this->clients = new ArrayCollection();
}
public function addClient(Client $client) {
$this->clients->add($client);
return $this;
}
public function removeClient(Client $client) {
if ($this->clients->contains($client)) {
$this->clients->remove($client);
}
return $this;
}
public function getClients() {
return $this->clients;
}
您的实体看起来不错(注释),不确定您是否真的需要 repositoryClass="App\Model\Repository\ClientRepository"
。
只要您让实体持久化一次,事物的顺序并不重要。
当通过 findBy
获取实体或将其添加到已持久化的实体时,实体会自动持久化。示例:
$server = $entityManager->getRepository('App\Model\Entity\Server')
->findOneByName('test');
$server->addClient(new Client());
// client and server are now both persisted
$entityManager->flush();
// stuff is now saved in the database
更新:
抱歉,我没有看到您已经有了 getter 和 setter。
更新架构时,请尝试以下操作:
./doctrine orm:clear-cache:metadata
./doctrine orm:schema-tool:update
./doctrine orm:generate-proxies
更新:
发现您的错误:
* @ORM\JoinColumn(name="server_id", referencedColumnName="id")
server_id
不存在。 Server::id
是,但不是 Server::server_id
:-)
正确:
* @ORM\JoinColumn(name="id", referencedColumnName="id")
关于php - 正确的对象实例化/持久化排序和注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24259717/