У меня проблема с наследованием одной таблицы, и я не уверен, правильно ли я интерпретирую документацию.
Первый: Я не скопировал сопоставления моего кода / сущностимногословно (или даже используя правильный синтаксис) здесь, так как я думаю, что проблема может быть лучше изложена абстрактно.Если это неприемлемо, скажите так, и я добавлю полный код - но он ДОЛГО и я думаю, что на мой вопрос можно ответить без него.
Если это поможет, я могу нарисовать диаграмму ER дляпопробуйте и сообщите, что я пытаюсь сделать.Если вы читаете следующее и думаете «эй, это должно сработать» - скажите мне, и я загружу реальный код
Второй: Я нигде не использую ленивую загрузку.Прежде чем получить доступ к своим сущностям, я проверяю, что загружаю каждую связанную сущность, к которой я собираюсь получить доступ, написав DQL заранее - поэтому следующая проблема довольно терминальна для моего приложения)
Настройка:
У меня есть несколько сущностей - они составляют ядро моего приложения.
// @entity AnimalTrainingSchool
// oneToMany: trainingDepartment
fields: [name / location / year founded]
// @entity trainingDepartment
oneToMany: animalTrainer
oneToOne: building
fields: [capacity]
// @entity animalTrainer
fields: [name / age / qualification]
Я получаю к ним доступ часто и в разных контекстах - но я обычно повторяю уровни и свойства доступа и отношения для этих объектов.
foreach ($animalTrainingSchool as $school){
echo $school->getName() . ' at ' . $school->getLocation();
echo 'These are the training departments for this school:';
foreach ($school->getTrainingDepartments as $trainingDepartment){
echo $trainingDepartment->getAnimalTypeTrained() . ' are trained in this department';
}
}
Я удостоверяюсь, что все онизагрузил сразу, сформировав мой DQL и выполнив его - чтобы ограничить количество SQL-запросов (до одного).Все это прекрасно работает (довольно стандартные вещи).
DQL Example : "SELECT ats, td, at FROM AnimalTrainingSchool ats JOIN AnimalTrainingSchool.trainingDepartments td JOIN td.animalTrainer at";
Это настраивает мою коллекцию и означает, что я могу пройти по ней без необходимости выполнять дополнительные запросы
Проблема:
Я сопоставил другие объекты в другом месте моего приложения - очень похоже на это (ПРИМЕЧАНИЕ: мой общий вопрос очень похож на приведенный ниже вопрос с одним ОСНОВНЫМ отличием (см. Ниже)
Доктрина 2 Отображение наследования с ассоциацией
// NB: new awards are issued each time they are awarded - so it is meant to be a oneToOne relationships - the awards are unique
// @entity award
{id information / table information / discriminator map / inheritance type (SINGLE_TABLE)}
fields: [medalMaterial / award_serial_number]
//departmentAward extends award
oneToOne: trainingDepartment
//trainerAward extends award
oneToOne: animalTrainer
Затем я установил двустороннюю связь, изменив свои начальные сущности
// @entity trainingDepartment
oneToMany: animalTrainer
oneToOne: building
oneToOne: departmentAward
fields: [capacity]
// @entity animalTrainer
fields: [name / age / qualification]
oneToOne: trainerAward
Что происходит
Теперь, когда я получаю доступ к своим исходным сущностям точно так же, как и выше - они автоматически (охотно) загружают ассоциированную сущность для своих наград, хотя я им не говорю. Это особенно плохо, когда я повторяю, хотяцелая куча trainingDepartments / AnimalTrainers и Doctrine выполняет оператор SQL для КАЖДОГО объекта.
Для 20 отделов с10 тренеров в каждом - это 200 дополнительных запросов.
//Given the exact same DQL and foreach loop as above (note that at no stage am I accessing awards) - I get a ton of extra queries that look like this
"SELECT award.property1, award.property2, award.property3 FROM awardTable LEFT JOIN trainingDepartmentTable ON award.awardee_id = trainingDepartmentTable.id and award.discriminatorColumn IN ('departmentAward')";
// or...
"SELECT award.property1, award.property2, award.property3 FROM awardTable LEFT JOIN animalTrainerTable ON award.awardee_id = animalTrainerTable.id and award.discriminatorColumn IN ('trainerAward')";
Ничего из того, что генерируется, неверно - просто, прочитав следующий вопрос, мне кажется, что я настроил это какдокументация описывает (и наоборот @Matthieu;а именно - если я связал мои начальные 3 энтита с сущностями уровня LOWEST, а не с базовым классом «вознаграждение», тогда они ДОЛЖНЫ иметь возможность использовать прокси вместо попыток активной загрузки сущностей.
StackoverflowВопрос, который задает противоположное тому, что я описываю
Доктрина 2 Отображение наследования с ассоциацией
Соответствующая документация доктрины
http://www.doctrine -project.org / docs / orm / 2.0 / en / reference / наследование-mapping.html # Performance-Impact
Существует общая производительностьРассмотрение с наследованием одной таблицы: если вы используете объект STI в качестве объекта «многие к одному» или «один к одному», вы никогда не должны использовать один из классов на верхних уровнях иерархии наследования как «targetEntity», только те, которыене имеет подклассов.В противном случае Doctrine НЕ МОЖЕТ создавать прокси-экземпляры этой сущности и ВСЕГДА будет загружать сущность с нетерпением.
Мне кажется, что независимо от того, присоединяетесь ли вы к сущности базового уровня или нетили объект подкласса - Doctrine будет охотно загружать ассоциации и не будет пытаться использовать прокси.
Опять же: я могу опубликовать реальный код - но учитывая длину вопроса, я чувствовал, что лучше не делать этого.Любой вклад приветствуется.