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

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

My use case is simple. There are two entities: Server and Client. 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.

上面的文档给出了一个非常简单的 exampleProductFeature实体,我试图为我的 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/

相关文章:

PHP - 计算多维数组中第一个元素的唯一值

php - 使用 PHP 显示来自 MySQL 数据库的图像

php - 为什么 PHP Doctine 的 free() 不工作?

php - 跨数据库连接学说

symfony - Symfony UniqueEntity与UniqueConstraint与Unique = true

php - 在 Codeigniter 中运行多个分号分隔的查询

php - 使用全局会产生任何开销吗?

来自 SQL 数据库表的 C# 类

php - 从 symfony 2 中的 Doctrine 2 实体中提取约束

doctrine - 没有附加语句的地方