Este foro ya no está activo, así que no puedes publicar nuevas preguntas ni responder a las preguntas existentes.

postPersist en una entidad relacionada

19 de mayo de 2015

Hola a todos, tengo dos entidades, podría decir un maestro y un detalle, la entidad maestro tiene una propiedad llamada total. Y la entidad Detalle tiene una propiedad Valor.

Estoy mostrando los formularios como una Colección de Formularios.

Lo que intento hacer es que al guardar la entidad me sume todos los valores de la entidad Detalle y los totalice en la entidad Maestro dentro de campo total.

lo que estoy intentando hacer es lo siguiente:

public function postPersist(LifecycleEventArgs $args) {
        $entity = $args->getEntity();
        $em = $args->getEntityManager();
 
        if ($entity instanceof Maestro) {
 
            $dql = 'SELECT SUM(d.value) AS total '
                    . 'FROM AppBundle:Detail d '
                    . 'WHERE d.maestro = :target'
            ;
 
            $totalize = $em->createQuery($dql)
                    ->setParameter('target', $entity->getId())
                    ->getSingleScalarResult();
 
            $entity->setTotalDeclared($totalize);
            $em->persist($entity);
            $em->flush();
        }
    }

Esto no me almacena ningún valor pero al modificar la consulta quitándole la cláusula WHERE y el setParameter, me suma todos los valores del campo value en el detalle.

Lo que no me funciona es con la condición, imagino yo que al no haberse guardado la entidad, no existe ningún $entity->getId()

Agradezco su valiosa colaboración para que me den una idea sobre como resolver esta duda. Voy a intentar resolverlo con Jquery directamente en el formulario aunque se que no es la mejor opción.

saludos,


Respuestas

#1

Hola de nuevo, ya conseguí la respuesta, me funcionó de la siguiente manera:

Se crea un EventListener para el evento onFlush así:

public function onFlush(OnFlushEventArgs $args)
{
    $em = $args->getEntityManager();
    $uow = $em->getUnitOfWork();
    $sum = 0;
 
    $entities = array_merge(
        $uow->getScheduledEntityInsertions(),
        $uow->getScheduledEntityUpdates()
    );
 
    foreach ($entities as $entity) {
        if(!($entity instanceof Detail )) {
            continue;
        }
 
        $sum = $sum + $entity->getValue();
        $det = $entity->getWarehouse();
        $det->setTotalDeclared($sum);
    }
}

Esta fue la forma que encontré para resolverlo, si alguien tiene algún comentario sobre esta solución o si de casualidad saben de algún otro método seria bueno compartirlo.

Aclaro que la solución no es de mi autoría, la encontré en el siguiente enlace

saludos

@miguelplazasr

19 mayo 2015, 18:46
#2

Buenas, lo que yo he hecho en algunos proyectos es algo como:

/**
 * @ORM\HasLifecycleCallbacks()
 */
class Maestro
{
   /**
    * @ORM\PrePersist()
    * @ORM\PreUpdate()
    */
   public function setTotalValue()
   {
       $total = 0;
       foreach($this->getDetails() as $detail){
           $total += $detail->getValue();
       }
 
       $this->setTotalDeclared($total);
   }
}

Simplemente creo un callback en la entidad, para que antes de crear o actualizar el objeto, calcule el total en base a los detalles.

Acá está la info de los Callbacks en entidades, Saludos!

@manuel_j555

19 mayo 2015, 21:03
#3

@manuel_j555 gracias por tu respuesta, lo hice tal como mencionas y me salió perfecto y es mucho mas sencillo.

Un saludo

@miguelplazasr

20 mayo 2015, 15:46