教义一对一,自引用不起作用

时间:2018-06-26 08:02:22

标签: postgresql doctrine-orm php-7.1 symfony-3.2

我正在处理旧版应用程序,现在我需要更改现有表(称为类别),以使其具有parent_id字段,该字段是其自身表(类别表)的主键的外键

我遇到的问题是我无法让Doctrine在数据库中设置父字段

我有以下实体orm:

ModelBundle\Entity\Category:
    type: entity
    table: category
    indexes:
        fki_parent_to_id:
            columns:
                - parent_id
    uniqueConstraints:
        uniq_64c19c1989d9b62:
            columns:
                - slug
        uniq_name:
            columns:
                - name
    id:
        id:
            type: integer
            nullable: false
            options:
                unsigned: false
            id: true
            generator:
                strategy: SEQUENCE
    fields:
        name:
            type: string
            nullable: false
            length: 255
            options:
                fixed: false
        slug:
            type: string
            nullable: false
            length: 255
            options:
                fixed: false
        description:
            type: string
            nullable: true
            length: 255
            options:
                fixed: false
        isActive:
            type: boolean
            nullable: false
            options:
                default: false
            column: is_active
        displayOrder:
            type: integer
            nullable: true
            options:
                unsigned: false
            column: display_order
    oneToOne:
        parent:
            targetEntity: Category
            joinColumns:
                parent_id:
                    referencedColumnName: id

    lifecycleCallbacks: {  }

这是实体类:

<?php

namespace ModelBundle\Entity;

use Doctrine\Common\Collections\Collection;
use JMS\Serializer\Annotation\Expose;

use Symfony\Cmf\Bundle\SeoBundle\Extractor\TitleReadInterface;
use Symfony\Cmf\Bundle\SeoBundle\Extractor\DescriptionReadInterface;
use Symfony\Cmf\Bundle\SeoBundle\Extractor\ExtrasReadInterface;

class Category implements ExtrasReadInterface, TitleReadInterface, DescriptionReadInterface
{
    /** @var int */
    private $id;

    /** @var string */
    private $slug;

    /**
     * @Expose
     *
     * @var string
     */
    private $name;

    /** @var bool */
    protected $isActive;

    /** @var string */
    private $description;

    /** @var Collection */
    private $products;

    /** @var int */
    private $displayOrder;

    /**
     * @var Category
     */
    private $parent;


    public function getId(): int
    {
        return $this->id;
    }

    public function setName(string $name): Category
    {
        $this->name = $name;
        return $this;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setIsActive(bool $isActive): Category
    {
        $this->isActive = $isActive;
        return $this;
    }

    public function getIsActive(): bool
    {
        return $this->isActive;
    }

    public function setDescription(string $description): Category
    {
        $this->description = $description;
        return $this;
    }

    public function getDescription(): string
    {
        return $this->description ?: '';
    }

    public function __construct()
    {
        $this->products = new \Doctrine\Common\Collections\ArrayCollection();
    }

    public function addProduct(Product $products): Category
    {
        $this->products[] = $products;
        return $this;
    }

    public function removeProduct(Product $products)
    {
        $this->products->removeElement($products);
    }

    public function getProducts(): Collection
    {
        return $this->products;
    }

    public function setSlug(string $slug): Category
    {
        $this->slug = $slug;
        return $this;
    }

    public function getSlug(): string
    {
        return $this->slug ?: '';
    }

    public function getSeoTitle(): string
    {
        return $this->getName();
    }

    public function getSeoDescription(): string
    {
        return $this->getDescription();
    }

    public function getSeoExtras(): array
    {
        return [
            'property' => [
                'og:title'       => $this->name,
                'og:description' => $this->description,
                'og:type'        => 'product:category'
            ],
        ];
    }

    function getDisplayOrder(): ?int
    {
        return $this->displayOrder;
    }

    public function setDisplayOrder($displayOrder): Category
    {
        $this->displayOrder = $displayOrder;
        return $this;
    }

    public function getParent() : Category
    {
        return $this->parent;
    }

    public function setParent(Category $parent): void
    {
        $this->parent = $parent;
    }

}

这映射了我上面所说的内容。   这类似于文档中的内容:https://www.doctrine-project.org/projects/doctrine-orm/en/2.5/reference/association-mapping.html#one-to-one-self-referencing   示例中没有Yaml,但我从教义中得到了这个Yaml(使用生成命令)。

无论我做什么,我都永远无法保存父级中设置的内容。

Example code:

$em = $this->get('doctrine')->getManager();
$repo = $em->getRepository(Category::class);

    $newCat = new Category();
    $newCat->setName('Test11');
    $newCat->setSlug('slug1');
    $newCat->setDescription('desc1');
    $newCat->setIsActive(true);
    $newCat->setDisplayOrder(1);
    $newCat->setParent($repo->find(11)); //<-- This does not get saved in the DB

    var_dump($newCat);

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

$repo->find(11)返回具有父级的Category实体(我在数据库中手动设置了该实体),但是父级字段为NULL。 (我也尝试过没有父对象的实体,结果相同) 这是var_dump:

object(ModelBundle\Entity\Category)[421]
  private 'id' => null
  private 'slug' => string 'slug1' (length=42)
  private 'name' => string 'Teste11' (length=33)
  protected 'isActive' => boolean true
  private 'description' => string 'desc1' (length=5)
  private 'products' => 
    object(Doctrine\Common\Collections\ArrayCollection)[422]
      private 'elements' => 
        array (size=0)
          empty
  private 'displayOrder' => int 1
  private 'parent' => 
    object(ModelBundle\Entity\Category)[435]
      private 'id' => int 11
      private 'slug' => string 'entertaining' (length=12)
      private 'name' => string 'Browse Entertaining' (length=19)
      protected 'isActive' => boolean false
      private 'description' => string 'Selection of great food for any occasion.' (length=41)
      private 'products' => 
        object(Doctrine\ORM\PersistentCollection)[458]
          private 'snapshot' => 
            array (size=0)
          protected 'initialized' => boolean false
      private 'displayOrder' => null
      private 'parent' => null

此代码在数据库中创建一个新类别,但父字段设置为NULL。

我在这里做错了什么?我需要怎么做才能将父级保存到数据库。 注意:我不想要oneToMany,我只希望一个类别拥有一个父母,仅此而已。

版本:

  

学说/注释v1.3.1

     

教义/缓存v1.6.1

     

学说/合集v1.4.0

     

主义/通用v2.7.2

     

教义/数据夹具v1.2.2

     

doctrine / dbal v2.5.12

     

主义/主义束1.6.7

     

doctrine / doctrine-cache-bundle 1.3.0

     

教义/教义治具套装v2.4.0

     

doctrine / doctrine-migrations-bundle v1.2.1

     

教义/变形器v1.1.0

     

主义/实例1.0.5

     

doctrine / lexer v1.0.1

     

学说/移民v1.5.0

     

主义/ orm v2.5.6

     

oro / doctrine-extensions 1.2.0

编辑: 抱歉,经过2天的尝试,我注意到该原理具有以下缓存(在symfony配置中):

orm:
    auto_generate_proxy_classes: "%kernel.debug%"
    entity_managers:
        default:
            naming_strategy: doctrine.orm.naming_strategy.underscore
            auto_mapping: true
            metadata_cache_driver: apcu
            query_cache_driver: apcu

一旦我删除了缓存,一切就开始起作用。 我正在手动删除缓存目录,但未能看到该教义也被apcu缓存。

0 个答案:

没有答案