Унаследованный объект со ссылками на себя ManyToMany: режим выборки EXTRA_LAZY не работает

Мне нужно выполнить следующие настройки: родительский класс

/**
 * @ORM\Entity()
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name = "discr", type = "string")
 */
abstract class DataCategory
{
    /**
     * @ORM\Column(name = "id", type = "integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy = "AUTO")
     */
    protected $id;

    //...
}

и несколько производных классов, которые содержат ссылки на родительский (здесь показан только один)

/**
 * @ORM\Entity
 */
class MultiCompoundDataCategory extends DataCategory
{
    /**
     * @ORM\ManyToMany(targetEntity = "DataCategory", fetch = "EXTRA_LAZY")
     * @ORM\JoinTable(name = "multi_compound_data_category_data_category",
     *      joinColumns = {@ORM\JoinColumn(name = "multi_compound_data_category", referencedColumnName = "id")},
     *      inverseJoinColumns = {@ORM\JoinColumn(name = "data_category", referencedColumnName = "id")})
     */
    public $summands;


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

Теперь при загрузке всех категорий MultiCompoundDataCategories через $this->getDoctrine()->getRepository(MultiCompoundDataCategory::class)->findAll(), выдается не только один выбор в MultiCompoundDataCategories (с объединением в ManyToMany-table). Вместо этого я получаю один основной запрос, за которым следует слагаемое по одному запросу для каждого, каждое с большой жирной последовательностью LEFT JOIN (также документы содержат предупреждение об этой проблеме, я массово ссылаюсь на нелистовые узлы дерева наследования).

BTW: Разве выборки LAZY уже недостаточно, чтобы избежать загрузки ManyToMany?

Исходя из этот комментарий, я предполагаю, что проблема в том, что мои дочерние объекты ссылаются на родительский. Как я могу это обойти? MappedSuperclass?

Может быть, абстрактный суперкласс - проблема?

olidem 10.10.2018 11:22
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
7
1
135
1

Ответы 1

Хорошо, я кое-что нашел, но не знаю, есть ли лучшее решение.

Сообщение Этот блог вдохновило меня на решение (последний абзац).

Выполняя соединение выборки DQL, я могу быстро загрузить дочернюю сущность с гидратированными ссылками. Итак, я загружаю дочерние классы все.

$all=[];
$all['sampled'] = $em->createQuery("SELECT s FROM ".SampledDataCategory::class." s")->getResult();
$all['compound'] = $em->createQuery("SELECT c, s, s2 FROM ".CompoundDataCategory::class." c JOIN c.cat1 s JOIN c.cat2 s2")->getResult();
$all['unary'] = $em->createQuery("SELECT u, s FROM ".UnaryDataCategory::class." u JOIN u.dataCategory s")->getResult();
$all['multi'] = $em->createQuery("SELECT m, s FROM ".MultiCompoundDataCategory::class." m JOIN m.summands s")->getResult();

После этого много запросов SELECT для каждой отдельной категории DataCategory, на которую имеется ссылка, не требуется, потому что диспетчер сущностей уже видел это.

Это звучит странно, но до сих пор мои тесты показывают, что 4 запроса с большой рабочей нагрузкой гидратации выполняются намного быстрее, чем ~ 800 одиночных выборок.

Другие вопросы по теме