[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Doctrine targetEntity abstract class
sNICkerssss
Doctrine-а выполняет лишние запросы, когда в entity прописана связь ManyToOne к абстрактному классу. Моя структура классов:
/**
* @ORM\Entity
* @ORM\Table(name="tb_payment_info")
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="type", type="integer")
* @ORM\DiscriminatorMap({
* "0" = "PaymentInfoPaypal",
* "1" = "PaymentInfoSkrill",
* })
*/
abstract class AbstractPaymentInfo
{
/**
* @ORM\Column(name="payment_info_id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
}

/**
* @ORM\Entity
* @ORM\Table(name="tb_payment_info_paypal")
*/
class PaymentInfoPaypal extends AbstractPaymentInfo
{
}

/**
* @ORM\Entity
* @ORM\Table(name="tb_payment_info_skrill")
*/
class PaymentInfoSkrill extends AbstractPaymentInfo
{
}

Мой Payout класс содержит колонку payment_info_id, значения которой берутся из таблицы tb_payment_info (общей для PaymentInfoPaypal и PaymentInfoSkrill):

/**
* @ORM\Entity
* @ORM\Table(name="tb_payout")
*/
class Payout
{
/**
* @var AbstractPaymentInfo
*
* @ORM\ManyToOne(targetEntity="AbstractPaymentInfo")
* @ORM\JoinColumn(name="payment_info_id", referencedColumnName="payment_info_id")
*/
private $paymentInfo;
}

Когда я пытаюсь получить любой Payout entity, его paymentInfo автоматически инициализируется с помощью отдельных запросов, которые следуют сразу после основного запроса:
$this->getEntityManager()->getRepository('TuoPayBundle:Payout')->find(255);

Получаю 2 запроса к базе: первый для Payout и второй для его paymentInfo
$this->getEntityManager()->getRepository('TuoPayBundle:Payout')->findBy(['id'=>[255,256] ]);

Получаю 3 запроса: первый для Payout а второй и третий для инициализации paymentInfo

Как получить lazy load?
redreem
напиши чистый нужный SQL. ох уж эти абстракции...
Игорь_Vasinsky
Цитата
напиши чистый нужный SQL. ох уж эти абстракции...

нафига, ему видимо объекты нужны, раз он ОРМ выбрал.

_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
sNICkerssss
Цитата (redreem @ 22.12.2015 - 01:04)
напиши чистый нужный SQL. ох уж эти абстракции...

1) Вариант, если джойним не сразу. Это как хочется чтобы работало).
$payout = $this->getEntityManager()->getRepository('TuoPayBundle:Payout')->find(255);

select * from tb_payout 
where id = 255

Lazy load:
$paymentInfo = $payout->getPaymnentInfo();

select * from tb_payment_info t0
left join tb_payment_info_paypal t1 ON t0.payment_info_id = t1.payment_info_id
left join tb_payment_info_skrill t2 ON t0.payment_info_id = t2.payment_info_id
where t0.payment_info_id = 33

Запрос выше - этот как раз лишний, который не по моей воле выполняется сейчас сам, когда делаю выборку Payout-ов

2) Вариант, если джойним сразу. Но этот вариант практически никогда не нужен. Джойн не маленький (в посте приведен пример не со всеми платежными системами) и само paymentInfo не всегда нужно.

$this->getEntityManager()->getRepository('TuoPayBundle:Payout')->createQueryBuilder('p')
->select('p', 'pi')
->join('p.paymentInfo', 'pi')
->where('p.id = 255')
->getQuery()
->getResult();



select * from tb_payout t0
left join tb_payment_info t1 ON t0.payment_info_id = t1.payment_info_id
left join tb_payment_info_paypal t2 ON t0.payment_info_id = t2.payment_info_id
left join tb_payment_info_skrill t3 ON t0.payment_info_id = t3.payment_info_id
where t0.id = 255
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.