【问题标题】:doctrine replace onetoone relation from inverse side学说从反面替换onetoone关系
【发布时间】:2021-05-01 02:43:52
【问题描述】:

我有两个实体ProductPrint 具有一对一的关系,其中Product 是父实体,Print 是子实体,但“拥有方”是Print(在数据库@ 987654326@ 表会有一个product_id 和外键)

产品:

<?php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity()
 */
class Product
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     */
    public int $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    public string $name;


    /**
     * @ORM\Column(type="text")
     */
    public string $description;

    /**
     * @ORM\Column(type="boolean")
     */
    public bool $available;


    /**
     * @ORM\OneToOne(targetEntity="Print", mappedBy="product", cascade={"persist", "remove"},  orphanRemoval=true)
     */
    public Print $print;


    public function __construct(
        int $id,
        string $name,
        string $description,
        bool $available,
    ) {
        $this->id = $id;
        $this->name = $name;
        $this->description = $description;
        $this-available = $available;
    }

    public function udpate(
        string $name,
        string $description,
        bool $available,
        Print $print,
    ) {
        $this->name = $name;
        $this->description = $description;
        $this-available = $available;
        $this->replacePrint($$print);
    }


    public function replacePrint(Print $print): void
    {
        $this->print = $print;
    }

}

和打印:

<?php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity()
 */
class Print
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    public int $id;

    /**
     * @ORM\Column(type="string")
     */
    public array $key;

    /**
     * @ORM\Column(type="string")
     */
    public array $value;

    /**
     * @ORM\OneToOne(targetEntity="Product", inversedBy="print")
     * @ORM\JoinColumn(name="product_id", referencedColumnName="id", nullable=false)
     */
    public Product $product;

    public function __construct(Product $product, string $key, string $value)
    {
        $this->product = $blueprint;
        $this->key = $key;
        $this->value = value;
    }
}

当我插入新产品时,一切都很好

$product = new Product($id, $name, $description, $available);
$product->replacePrint(new Print($product, $key, $value));

$em->persist($product);
$em->flush

它正在插入产品和相关的印刷品,为印刷品生成新的 id

但是现在我想更新产品时:

$product = $em->find(Product::class, $id);
$product->udpate($name, $description, $available);
$product->replacePrint(new Print($product, $key, $value));

$em->persist($product);
$em->flush

我收到错误Cannot assign null to property App\\Entity\\Print::$id of type int

【问题讨论】:

  • 我尝试使用 orphanRemoval=true 将其添加到 Product 和 Print 并完全删除,但仍无法按预期工作
  • 您只需要persist 新实体(当您插入时),我不是 100% 对此,但我认为您只需要保留新的 Print 实体,而且您有在您的级联注释之后的双 , - 也许就是这样
  • double , 这里只是拼写错误,因为我没有显示真实代码,它是简化版本,我做了一个类型,我会修复一个拼写错误。关于只保留Print,这是没有意义的,我的主要实体是Product,这就是为什么我们有这个级联/孤儿选项,以便能够用一个主要实体持久化所有嵌套实体。在实际代码中,我的 Product 依赖于超过 5 个子对象,我不想单独保留它们中的每一个。

标签: php doctrine-orm doctrine


【解决方案1】:

你必须坚持 New Print 实体:

$product = $em->find(Product::class, $id);
$product->udpate($name, $description, $available);
$print = new Print($product, $key, $value);
$product->replacePrint($print);

$em->persist($print);

$em->persist($product);
$em->flush();

【讨论】:

  • 嗯,2 个问题:1. 为什么我不需要它来创建(正如我在产品创建时所说的那样,它也可以在没有明确持久化的情况下创建打印)2)cascade={"persist"} 然后是什么(@ 987654321@)???
猜你喜欢
  • 2016-09-04
  • 1970-01-01
  • 2021-01-17
  • 2017-01-22
  • 2011-08-29
  • 2023-04-06
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多