原则-更新外键

时间:2018-10-27 18:07:54

标签: php mysql database doctrine-orm

我有描述产品的实体。每个产品可能都有翻译(ProductTranslation实体)。产品具有主键:code,在翻译实体(product_code)中用作外键。在翻译实体中,product_codelanguage_code的组合用作键。

这些是我的实体:

<?php
declare(strict_types=1);

namespace Entity;

use Doctrine\Common\Collections\ArrayCollection;

/**
 * Class Product
 * @package Entity
 * @Entity @Table(name="product")
 */
class Product
{
    /**
     * @Id
     * @var string
     * @Column(type="string", length=3)
     */
    protected $code;

    /**
     * @OneToMany(targetEntity="ProductTranslation", mappedBy="product", cascade={"persist", "remove"})
     */
    private $translations;

    public function __construct()
    {
        $this->translations = new ArrayCollection();
    }

    public function getCode(): string
    {
        return $this->code;
    }

    public function setCode(string $code): void
    {
        $this->code = $code;
    }

    public function getTranslations()
    {
        return $this->translations;
    }

    public function addTranslation(ProductTranslation $productTranslation)
    {
        $this->translations->add($productTranslation);
    }

    public function setTranslations($translations): void
    {
        $this->translations = $translations;
    }

    public function clearTranslations()
    {
        $this->translations->clear();
    }
}

和:

<?php
declare(strict_types=1);

namespace Entity;

/**
 * Class ProductTranslation
 * @package Entity
 * @Entity @Table(name="product_translation")
 */
class ProductTranslation
{
    /**
     * @ManyToOne(targetEntity="Product", inversedBy="translations", cascade={"persist", "remove"})
     * @JoinColumn(name="product_code", referencedColumnName="code")
     * @Id
     */
    private $product;

    /**
     * @var string
     * @Column(type="string", name="language_code", length=5)
     * @Id
     */
    protected $languageCode;

    /**
     * @var string
     * @Column(type="string", name="product_name", length=128)
     */
    protected $productName;

    public function getLanguageCode(): string
    {
        return $this->languageCode;
    }

    public function setLanguageCode(string $languageCode): void
    {
        $this->languageCode = $languageCode;
    }

    public function getProductName(): string
    {
        return $this->productName;
    }

    public function setProductName(string $product): void
    {
        $this->productName = $product;
    }

    public function getProduct(): Product
    {
        return $this->product;
    }

    public function setProduct($product): void
    {
        $this->product = $product;
    }
}

我喜欢编辑产品,包括产品代码,这是我的代码。

$newTranslations = ['en' => 'name_en', 'de' => 'name_de', 'fr' => 'name_fr'];
$newData = ['originalCode' => 'pr1', 'code' => 'pr2', 'translations' => $newTranslations];

/** @var Product $product */
$product = $entityManager->getRepository(Product::class)->findOneBy(['code' => $newData['originalCode']]);
$product->setCode($newData['code']);
$currentTranslations = $product->getTranslations();

// for update existing translation or create new if doesn't exist
foreach ($newData['translations'] as $code => $translation) {
    $found = false;

    /** @var ProductTranslation $currentTranslation */
    foreach ($currentTranslations as $currentTranslation) {
    if ($currentTranslation->getLanguageCode() == $code) {
        $currentTranslation->setProductName($translation);
        $found = true;
        break;
    }

    if (!$found) {
        $newTranslation = new ProductTranslation();
        $newTranslation->setProduct($product);
        $newTranslation->setLanguageCode($code);

        $this->entityManager->persist($newTranslation);
        $product->addTranslation($newTranslation);
    }
}

$entityManager->flush($product);

运行此代码时,我得到:

Fatal error: Uncaught Doctrine\DBAL\Driver\Mysqli\MysqliException: Cannot delete or update a parent row: a foreign key constraint fails (`doctrine`.`product_translation`, CONSTRAINT `FK_1846DB70FAFD1239` FOREIGN KEY (`product_code`) REFERENCES `product` (`code`)) in /var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php on line 69

我一直在尝试解决它的许多方法(使用cascase进行实验,在编辑翻译时将产品设置为循环等),但是没有任何效果。我的做法有什么不妥?

0 个答案:

没有答案