Symfony - Doctrine Single Table 与父实体的继承 ManyToOne 关联
Symfony - Doctrine Single Table Inheritance ManyToOne association with parent entity
我正在做一个用 Symfony 3.1.10 制作的项目。
我有三个实体:
我的实体 1->n 我的数据透视实体
MyPivotEntity n->1 MySuperInheritanceEntity
我还有另一个实体 MyInheritanceEntity,它继承自 MySuperInheritanceEntity,具有 single_table 继承
我在 MyEntityType 表单中创建了 MyPivotEntity 的 CollectionType 字段,但是当我从控制器创建表单时,我收到内存超出消息,因为构建器为每个 MySuperInheritanceEntity 执行数据库请求。我怎样才能防止这种情况发生?在这种情况下,我根本不需要 MySuperInheritanceEntity 信息,我只需要 MyPivotEntity 字段
<?php
/**
* MyEntity
*
* @ORM\Table(name="my_entity")
* @ORM\Entity()
*/
class MyEntity {
/**
* @ORM\OneToMany(targetEntity="MyPivotEntity", mappedBy="myEntity", cascade={"persist"})
*/
private $myPivotEntity;
}
/**
* MyPivotEntity
*
* @ORM\Table(name="my_pivot_entity")
* @ORM\Entity()
*/
class MyPivotEntity {
/**
* @ORM\ManyToOne(targetEntity="MyEntity", inversedBy="myPivotEntity", cascade={"persist"})
*/
private $myEntity;
/**
* @ORM\ManyToOne(targetEntity="MySuperInheritanceEntity", inversedBy="myPivotEntity", cascade={"persist"})
*/
private $mySuperInheritanceEntity;
}
/**
* MySuperInheritanceEntity
*
* @ORM\Table(name="my_super_inheritance_entity")
* @ORM\Entity()
* @ORM\InheritanceType("SINGLE_TABLE")
*/
class MySuperInheritanceEntity {
/**
* @ORM\OneToMany(targetEntity="MyPivotEntity", mappedBy="mySuperInheritanceEntity")
*/
private $myPivotEntity;
}
/**
* MyInheritanceEntity
*
* @ORM\Table(name="my_inheritance_entity")
* @ORM\Entity()
*/
class MyInheritanceEntity extends MySuperInheritanceEntity {
}
class MyEntityType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('myPivotEntity', CollectionType::class, [
'entry_type' => MyPivotEntityType::class
]);
}
}
class MyPivotEntityType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('somField');
}
}
class MyController extends Controller {
/**
* @Post("/myEntity/update")
*/
public function postMyEntityUpdateAction(Request $request, MyEntity $myEntity) {
$form = $this->createForm(MyEntityType::class, $myEntity);
// here error 500 because of too mach memory
// caused by the MyPivotEntityType which runs a request for each entry,
// trying to retrieve all the information about MySuperInheritanceEntity and MyInheritanceEntity
// even if I don't need it at all
// because of the @ORM\InheritanceType("SINGLE_TABLE")
// deleting the inheritance solves the problem, but I need it
$form->handleRequest($request);
if ($form->isValid()) {
$this->getEm()->flush();
return ['success' => true];
}
$errors = (string) $form->getErrors(true, false);
throw new HttpException(400, $errors);
}
}
文档 says:
There is a general performance consideration with Single Table Inheritance: If the target-entity of a many-to-one or one-to-one
association is an STI entity, it is preferable for performance reasons that it
be a leaf entity in the inheritance hierarchy, (ie. have no subclasses).
另请注意:
对 OneToMany 关联属性名称使用复数名称:
class MyEntity {
/**
* @ORM\OneToMany(targetEntity="MyPivotEntity", mappedBy="myEntity", cascade={"persist"})
*/
private $myPivotEntities;
}
更新
作为替代方法,您可能会完全忘记继承并拥有单独的(以前是子的)实体,所有属性和关联都已复制。
我正在做一个用 Symfony 3.1.10 制作的项目。
我有三个实体:
我的实体 1->n 我的数据透视实体
MyPivotEntity n->1 MySuperInheritanceEntity
我还有另一个实体 MyInheritanceEntity,它继承自 MySuperInheritanceEntity,具有 single_table 继承
我在 MyEntityType 表单中创建了 MyPivotEntity 的 CollectionType 字段,但是当我从控制器创建表单时,我收到内存超出消息,因为构建器为每个 MySuperInheritanceEntity 执行数据库请求。我怎样才能防止这种情况发生?在这种情况下,我根本不需要 MySuperInheritanceEntity 信息,我只需要 MyPivotEntity 字段
<?php
/**
* MyEntity
*
* @ORM\Table(name="my_entity")
* @ORM\Entity()
*/
class MyEntity {
/**
* @ORM\OneToMany(targetEntity="MyPivotEntity", mappedBy="myEntity", cascade={"persist"})
*/
private $myPivotEntity;
}
/**
* MyPivotEntity
*
* @ORM\Table(name="my_pivot_entity")
* @ORM\Entity()
*/
class MyPivotEntity {
/**
* @ORM\ManyToOne(targetEntity="MyEntity", inversedBy="myPivotEntity", cascade={"persist"})
*/
private $myEntity;
/**
* @ORM\ManyToOne(targetEntity="MySuperInheritanceEntity", inversedBy="myPivotEntity", cascade={"persist"})
*/
private $mySuperInheritanceEntity;
}
/**
* MySuperInheritanceEntity
*
* @ORM\Table(name="my_super_inheritance_entity")
* @ORM\Entity()
* @ORM\InheritanceType("SINGLE_TABLE")
*/
class MySuperInheritanceEntity {
/**
* @ORM\OneToMany(targetEntity="MyPivotEntity", mappedBy="mySuperInheritanceEntity")
*/
private $myPivotEntity;
}
/**
* MyInheritanceEntity
*
* @ORM\Table(name="my_inheritance_entity")
* @ORM\Entity()
*/
class MyInheritanceEntity extends MySuperInheritanceEntity {
}
class MyEntityType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('myPivotEntity', CollectionType::class, [
'entry_type' => MyPivotEntityType::class
]);
}
}
class MyPivotEntityType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('somField');
}
}
class MyController extends Controller {
/**
* @Post("/myEntity/update")
*/
public function postMyEntityUpdateAction(Request $request, MyEntity $myEntity) {
$form = $this->createForm(MyEntityType::class, $myEntity);
// here error 500 because of too mach memory
// caused by the MyPivotEntityType which runs a request for each entry,
// trying to retrieve all the information about MySuperInheritanceEntity and MyInheritanceEntity
// even if I don't need it at all
// because of the @ORM\InheritanceType("SINGLE_TABLE")
// deleting the inheritance solves the problem, but I need it
$form->handleRequest($request);
if ($form->isValid()) {
$this->getEm()->flush();
return ['success' => true];
}
$errors = (string) $form->getErrors(true, false);
throw new HttpException(400, $errors);
}
}
文档 says:
There is a general performance consideration with Single Table Inheritance: If the target-entity of a many-to-one or one-to-one association is an STI entity, it is preferable for performance reasons that it be a leaf entity in the inheritance hierarchy, (ie. have no subclasses).
另请注意:
对 OneToMany 关联属性名称使用复数名称:
class MyEntity {
/**
* @ORM\OneToMany(targetEntity="MyPivotEntity", mappedBy="myEntity", cascade={"persist"})
*/
private $myPivotEntities;
}
更新
作为替代方法,您可能会完全忘记继承并拥有单独的(以前是子的)实体,所有属性和关联都已复制。