0

Why are Proxy classes created instead of entity objects?

DoctrineORMModule\Proxy\__CG__\App\Entity\FormType vs \App\Entity\FormType 

Setup: Laminas, Doctrine ORM

 Class Project{} Class ProjectForm { /** * @ORM\Id * @ORM\Column(name="id") * @ORM\GeneratedValue */ protected $id; /** * @ORM\OneToOne(targetEntity="FormType") * @ORM\JoinColumn(name="form_type_id", referencedColumnName="id") */ protected $formType; /** * @ORM\OneToOne(targetEntity="Project") * @ORM\JoinColumn(name="project_id", referencedColumnName="id") */ protected $project; /** * @ORM\Column(name="label") */ protected $label; /** * @ORM\Column(name="status") */ protected $status; /** * @ORM\Column(name="order_nr") */ protected $order; } Class FormType {/** * @ORM\Id * @ORM\Column(name="id") * @ORM\GeneratedValue */ protected $id; /** * @ORM\Column(name="code") */ protected $code; /** * @ORM\Column(name="label_txt") */ protected $label; : : } 

Then, using a custom extended Repository use the query builder to get data from storage

 $qb->select('pc','ft') ->from(\App\Entity\ProjectForm::class,'pc') ->join(\App\Entity\FormType::class,'ft') ->where($qb->expr()->eq('pc.project',$projectId)) ->andWhere('pc.formType=ft.id'); 

SQL Generated is/seems correct (when passing project ID 1) and returns the correct number of rows

SELECT p0_.id AS id_0, p0_.label AS label_1, p0_.status AS status_2, p0_.order_nr AS order_nr_3, f1_.id AS id_4, f1_.code AS code_5, f1_.label_txt AS label_txt_6, p0_.form_type_id AS form_type_id_7, p0_.project_id AS project_id_8 FROM project_forms p0_ INNER JOIN form_types f1_ WHERE p0_.project_id = 1 AND p0_.form_type_id = f1_.id 

The same resultset is visible via

$this->getEntityManager()->getRepository(\Eho\Core\Entity\ProjectForm::class)->findBy(['project'=>$projectId],[]); 

With $result[0]->getProject()->getTitle() returning the correct string but $result[0]->getFormType()->getName() throwing and error due to class \DoctrineORMModule\Proxy\__CG__\Entity\FormType being returned from getFormType()...???

Project::getTite() -> string ProjectForm->getName() -> string 

EDIT: Also tried different join for giggles

$joinOn = \Doctrine\ORM\Query\Expr\Join::ON; $joinWith = \Doctrine\ORM\Query\Expr\Join::WITH; $qb->select('pf','ft') ->from(\App\Entity\ProjectForm::class,'pf') ->innerJoin(\App\Entity\FormType::class,'ft',$joinWith, 'pf.formType=ft.id') ->where($qb->expr()->eq('pf.project',$projectId)); 

With SQL generated:

SELECT ...fields... FROM project_forms p0_ INNER JOIN form_types f1_ ON (p0_.form_type_id = f1_.id) WHERE p0_.project_id = 1

But the same resultsets (with Proxy classes are returned)...

Why is ONE entity (project) populated correctly and another (formType) as a proxy...?

7
  • I think I've found a 'workaround' but it does not explain why the proxy is created. Using the last $qb method (innerJoin) I swap the from() and innerJoin() entities and it works....? Why? It seems that one has to 'select' from the referenced/associated entity. Why was projects fine then...? Any explainations/insights much appreciated Commented May 20, 2021 at 7:24
  • Does this answer your question? What is a Proxy in Doctrine 2? Commented May 20, 2021 at 7:59
  • Proxies are used to support lazy loading of associated entities. The Doctrine manual has a section which discusses this. Load all your entities via a custom query and no proxies will be used. In theory it should not make any difference to the rest of your code. Commented May 20, 2021 at 12:14
  • Thanks @cerad So is the Query Builder not a 'customer query'? Also, the 'What is a proxy' link I've read but still not clear why Lazy loading is used IF I've joined the tables to populate the correct entity... I.e. I understand that you can use $e1 = $em->find() to get the base entity, then if that has associations ($e1->getProject() ) will be affected by EAGER vs LAZY loading. BUT I've already requested the data I need via a join. No lazy or eager needed... Commented May 21, 2021 at 5:28
  • Also, does not address why 1 associated entity (Project) was populated without a proxy and another (FormType) was not and had a proxy. Commented May 21, 2021 at 5:30

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.