Symfony - Doctrine Single Table Inheritance Ассоциация ManyToOne с родительским объектом - PullRequest
0 голосов
/ 23 октября 2018

Я работаю над проектом, созданным в Symfony 3.1.10.

У меня есть три объекта

MyEntity 1-> n MyPivotEntity

MyPivotEntity n-> 1 MySuperInheritanceEntity

и у меня есть еще одна сущность MyInheritanceEntity, которая наследуется от MySuperInheritanceEntity с наследованием single_table

https://www.doctrine -project.org / projects / doctrine-orm / en / 2.6 / reference / наследование-mapping.html # single-table-наследование

Я создал поле CollectionType MyPivotEntity в форме MyEntityType, но когда я создаю команду из контроллера, я получаю сообщение о превышении памяти, потому что сборщик делает базу данныхзапрос для каждого 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 wich runs a request for each entry,
        // trying to retrive 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);
    }
}

1 Ответ

0 голосов
/ 23 октября 2018

Документация говорит :

Существует общее соображение производительности с наследованием одной таблицы: если целевым объектом является множество-к-одному или один-к-одномуодна ассоциация является объектом STI, предпочтительно из соображений производительности это должен быть конечный объект в иерархии наследования (т. е. не иметь подклассов).

Также имейте в виду:

использовать множественные имена для имен свойств ассоциации OneToMany:

class MyEntity {
        /**
         * @ORM\OneToMany(targetEntity="MyPivotEntity", mappedBy="myEntity", cascade={"persist"})
         */
        private $myPivotEntities;
}

Обновление

В качестве альтернативы вы можете полностью забыть о наследовании и иметь отдельные (ранее дочерние) сущности со всеми свойствамии ассоциации тиражируются.

...