2012-02-21 17 views
9

Quiero salvar a uno de mi entidad de objetos en la sesión, pero como yo estoy haciendo así, yo estoy poniendo los dos errores siguientes:Symfony2 entidad serializar objetos a la sesión

Excepción: Symfony \ Bundle \ FrameworkBundle \ Recopilador de Datos \ RequestDataCollector :: serialize() debe devolver una cadena o NULL

y

ErrorException: Aviso: serial ize(): "id" devuelto como miembro variable de __sleep() pero no existe en /var/www/clients/client71/web256/web/_dev_fd/kkupon/vendor/symfony/src/Symfony/Component/HttpKernel /DataCollector/DataCollector.php línea 29

Mi código es el siguiente:

$offer = $this->getEntityManager()->getRepository('KkuponMainBundle:Offer')->find($offer_id); 
$request->getSession()->set('offer', $offer); 

¿Cómo podría hacerlo bien?

Gracias.

ACTUALIZACIÓN Con la ayuda de Rowgm, pude solucionar este problema estableciendo propiedades protegidas en lugar de privadas. El único problema que tengo es después de leyendo la entidad de la sesión que el EntityManager no conoce, y si agrego el objeto (desde la sesión) a otro objeto (hay una relación OneToMany entre ellos), no lo hará trabajo.

<?php 
$offer = $this->get('session')->get('offer'); 
$coupon = new Coupon(); 
$coupon->setOffer($offer); 
$this->em->persist($coupon); 
$this->em->flush(); 

Esto generará un error, porque cupón tiene una propiedad de objeto que según el EntityManager no está en la base de datos (en realidad es en el PP, puse a la sesión de la BD).

<?php 
$offer = $this->get('session')->get('offer'); 
echo $this->em->getUnitOfWork()->isInIdentityMap($offer) ? "yes":"no"; //result: no 

Una solución puede ser: $offer = $this->em->merge($offer);

Pero ésto no parece ser la mejor. Me gustaría que mi EntityManager perciba los objetos de entidad almacenados en sesión sin decirlo cada vez. ¿Alguna idea?

Respuesta

14

Puede serializar cualquier entidad configurando todas sus propiedades y relaciones desde privado hasta protegido.

Puede tener un problema común con symfony2, incluso si ha configurado todas las propiedades como protegidas: Debe volver a generar los proxies de las entidades que ha modificado. Para hacerlo, simplemente borre la caché.Para dev ambiente:

app/console cache:clear

Funciona incluso si "que contiene muchos objetos extraños e incluso ArrayCollections de entidades extranjeras" como usted ha dicho.

+0

Gracias, ayudó mucho. –

+0

Por favor, si puede, responda la parte de actualización de mi pregunta. –

+0

Piénselo: si almacena toda esa entidad, almacenará un objeto grande en sus datos de sesión. Para su entorno de desarrollo, no es un problema. Pero si tienes muchos usuarios, es un desperdicio de recursos. La solución es tan simple: almacenar la identificación del objeto y usar el método find() del repositorio para recuperar el objeto. Al final, es lo mismo. –

6

Entidades de serialización no se recomienda, como se puede ver en el Doctrine-documentation. Debe implementar el Serializable-interface y serializar/deserializar los datos de entidad manualmente.

+0

números de serie a mi entidad podría ser problemático, ya que contiene muchos objetos extraños e incluso ArrayCollections de entidades extranjeras. ¿Alguna idea mejor que solo almacenar la identificación y recuperar el objeto de la base de datos cada vez que lo necesito? –

+0

Como puede ver en su excepción, al ponerlo en una sesión se serializará, eso es lo que está causando el error. Pero como dices, debido a la complejidad de tu objeto, probablemente deberías ir guardando la identificación y recuperar el objeto de la base de datos nuevamente. Posiblemente usar algún tipo de caché de objetos también podría funcionar, pero no estoy seguro. – dbrumann

+1

Gracias, solo voy a guardar la identificación. –

2

Usted puede excluir campos unnesseary por overridding __sleep método:

public function __sleep() { 

    // these are field names to be serialized, others will be excluded 
    // but note that you have to fill other field values by your own 
    return array('id', 'username', 'password', 'salt'); 
} 
Cuestiones relacionadas