正确的对象实例化/持久性排序和注释

时间:2014-06-17 09:04:05

标签: php orm doctrine-orm one-to-many

  

我的用例很简单。有两个实体:ServerClient每个服务器都可以拥有多个客户端。这真的很简单......

我需要什么

因此我需要以下内容:

  • 调用$server->getClients()将返回与该服务器关联的所有Client个实体
  • 调用$client->getServer()将返回与该客户关联的Server实体

我认为,根据documentation,这是一对多双向关系。

  

除非您使用其他连接表,否则一对多关联必须是双向的。这是必要的,因为在“许多”方面定义了一对多关联中的外键。 Doctrine需要一个多对一的关联来定义这个外键的映射。

上面的文档提供了一个非常简单的exampleProductFeature个实体,我试图为ServerClient用例采用这些实体

问题

首先,我似乎无法正确创建Client实体,将其分配给新创建的Server实体,然后保留/保存它们。 Client实体的null属性始终为server_id。需要什么订购?为什么我的注释不起作用?

其次,我无法弄清楚我是否需​​要一个联接表才能$client->getServer()或相反:$server->getClients()我是否需要连接表才能满足上述条件?我还是尝试添加连接表,但在运行doctrine orm:schema-tool:update时实际上没有创建连接表。

守则

注意:ClientServer

我的两端都有Setters / Getters
/**
 * 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;
}

我尝试了多种创建ClientServer实体的组合,调用$server->addClient(new Client));等,并以不同的顺序和更多订单持续存在。

完全我做错了什么?为什么我有null?为了实现方法::getClients()::getServer()可用于修复我的注释和对象持久性,我需要什么?

1 个答案:

答案 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")