我正在处理旧版应用程序,现在我需要更改现有表(称为类别),以使其具有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缓存。