我的用例很简单。有两个实体:
Server
和Client
。 每个服务器都可以拥有多个客户端。这真的很简单......
因此我需要以下内容:
$server->getClients()
将返回与该服务器关联的所有Client
个实体$client->getServer()
将返回与该客户关联的Server
实体我认为,根据documentation,这是一对多双向关系。
除非您使用其他连接表,否则一对多关联必须是双向的。这是必要的,因为在“许多”方面定义了一对多关联中的外键。 Doctrine需要一个多对一的关联来定义这个外键的映射。
上面的文档提供了一个非常简单的example个Product
和Feature
个实体,我试图为Server
到Client
用例采用这些实体
首先,我似乎无法正确创建Client
实体,将其分配给新创建的Server
实体,然后保留/保存它们。 Client
实体的null
属性始终为server_id
。需要什么订购?为什么我的注释不起作用?
其次,我无法弄清楚我是否需要一个联接表才能$client->getServer()
或相反:$server->getClients()
。 我是否需要连接表才能满足上述条件?我还是尝试添加连接表,但在运行doctrine orm:schema-tool:update
时实际上没有创建连接表。
注意:Client
和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()
可用于修复我的注释和对象持久性,我需要什么?
答案 0 :(得分:1)
你需要确保mutators(getter和setter)方法存在(afaik,至少在我的学说版本中)getter setter不是由doctrine生成的,你需要实现它们。数组集合必须在contstructor中:
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
<强>更新
对不起,我没有读到你已经有吸气剂和制定者。
更新架构时,请尝试以下操作:
./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")