Мне нужно выполнить следующие настройки: родительский класс
/**
* @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?





Хорошо, я кое-что нашел, но не знаю, есть ли лучшее решение.
Сообщение Этот блог вдохновило меня на решение (последний абзац).
Выполняя соединение выборки 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 одиночных выборок.
Может быть, абстрактный суперкласс - проблема?