Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 serialize entity object to session

I want to save one of my entity objects into the session, but as I'm doing so, I'm getting the following two errors:

Exception: Symfony\Bundle\FrameworkBundle\DataCollector\RequestDataCollector::serialize() must return a string or NULL

and

ErrorException: Notice: serialize(): "id" returned as member variable from __sleep() but does not exist in /var/www/clients/client71/web256/web/_dev_fd/kkupon/vendor/symfony/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php line 29

My code goes like this:

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

How could I get it right?

Thank you.

UPDATE With Rowgm's help I could fix this problem by setting properties protected instead of private. The only problem I have is after reading the entity from the session the EntityManager does not know about it, and if I add the object(from the session) to another object(there is OneToMany relationship between them), it won't work.

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

This raises an error, because coupon has an object property which according to the EntityManager is not in the database(actually it is in the DB, I put to the session from the DB).

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

One solution can be: $offer = $this->em->merge($offer);

But this doesnt seem to be the best one. I'd like my EntityManager to perceive entity objects stored in session without telling it each time. Any idea?

like image 342
David Frank Avatar asked Feb 21 '12 20:02

David Frank


3 Answers

You can serialize any entity by setting all their properties and relationships from private to protected.

You could have a common issue with symfony2, even if you have set all properties to protected: You have to re-generate the proxies of those entities you have changed. To do so, simply clear the cache. For dev enviroment:

app/console cache:clear

It works even if "it contains many foreign objects and even ArrayCollections of foreign entities" as you said.

like image 89
Rowinson Gallego Avatar answered Nov 09 '22 21:11

Rowinson Gallego


Serializing entities is not recommended, as you can see in the Doctrine-documentation. You should implement the Serializable-interface and serialize/deserialize the entity-data manually.

like image 36
dbrumann Avatar answered Nov 09 '22 23:11

dbrumann


You can exclude unnesseary fields by overridding __sleep method:

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');
}
like image 2
pleerock Avatar answered Nov 09 '22 23:11

pleerock