Tengo en mi proyecto Symfony 5, 2 entidades: Cliente y Plantilla. Cada Cliente tiene una o más plantillas (OneToMany), cada plantilla se relaciona con un solo Cliente (ManyToOne). Tengo una función getTemplates() en Client.php que devuelve una colección de plantillas.
El problema que tengo es que cuando llamo a la función getTemplates() la ejecuto desde:
$client = $entityManager->getRepository(Client::class)->find($id); $templates = $client->getTemplates();Obtengo una colección inicializada = falsa .
Por lo que entiendo, para evitar solicitudes innecesarias, Symfony crea un objeto de proxy de plantilla que es nulo . Para que esto funcione, puedo agregar fetch="EAGER"
@ORM\OneToMany(targetEntity=Template::class, mappedBy="Client", orphanRemoval=true, fetch="EAGER")Agregar esto básicamente hace que solicite el objeto Plantilla "real" ( más información aquí ).
Lo que me gustaría hacer es hacer que mi getTemplates funcione sin tener que solicitar todas las plantillas cuando recupero todos mis clientes como aquí (a veces solo necesito mostrar todos los clientes y luego solicitar las plantillas de un determinado cliente):
$templateRepository->findAll()Sé cómo resolver mi problema, solo me gustaría tener la mejor manera de hacerlo y tener la menor cantidad de solicitudes a mi base de datos (básicamente solo llamándola cuando la necesito).
En resumen, me gustaría:
Como explicó Yassinefikri , el comportamiento predeterminado de Symfony es no solicitar las Entidades vinculadas para evitar un mal rendimiento.
Para resolver el problema, necesita una función adecuada en el repositorio donde buscará los Clientes y los unirá con sus Plantillas.
Esto permite obtener todos los Clientes sin su Plantilla, pero también poder obtener todos los Clientes con sus Plantillas, independientemente de si lo necesita o no.
Cambiar el comportamiento predeterminado de Symfony agregando un fetch="EAGER" no es una buena práctica, siempre debe crear una función para un resultado deseado en lugar de cambiar el comportamiento predeterminado (lo que disminuiría el rendimiento, especialmente si se trata de una base de datos grande) .
- EDITAR , Mejor (y más optimizada) forma de resolver el problema
Como dijo Will B , el comportamiento proviene de Doctrine ORM y no de Symfony (Symfony se usa con frecuencia con Doctrine ORM pero esto se aplica a ORM en general) .
Otra (y mejor) forma de lograr el resultado deseado es inicializar el objeto (que buscará las entidades vinculadas sin realizar solicitudes JOIN a la base de datos - initializeObject() ).
PARA RESUMIR
NUNCA use fetch="EAGER" si puede, ya que esta es realmente la forma de trabajo de tratar con entidades vinculadas, es mejor usar la solución del problema de Will B o Yassinefikri .