Symfony2 将实体对象序列化到会话
我想将我的实体对象之一保存到会话中,但当我这样做时,我收到以下两个错误:
异常: Symfony\Bundle\FrameworkBundle\DataCollector\RequestDataCollector::serialize() 必须返回字符串或 NULL
并且
ErrorException:注意:serialize():“id”作为成员返回 来自 __sleep() 的变量,但不存在于 /var/www/clients/client71/web256/web/_dev_fd/kkupon/vendor/symfony/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php 第29行
行 我的代码是这样的:
$offer = $this->getEntityManager()->getRepository('KkuponMainBundle:Offer')->find($offer_id);
$request->getSession()->set('offer', $offer);
我怎样才能做到正确?
谢谢。
更新 在 Rowgm 的帮助下,我可以通过将属性设置为受保护而不是私有来解决此问题。我遇到的唯一问题是在从会话中读取实体后,EntityManager 不知道它,并且如果我将对象(从会话中)添加到另一个对象(它们之间存在 OneToMany 关系) ,它不会起作用。
<?php
$offer = $this->get('session')->get('offer');
$coupon = new Coupon();
$coupon->setOffer($offer);
$this->em->persist($coupon);
$this->em->flush();
这会引发错误,因为优惠券有一个对象属性,根据 EntityManager,该属性不在数据库中(实际上它在数据库中,我从数据库放入会话中)。
<?php
$offer = $this->get('session')->get('offer');
echo $this->em->getUnitOfWork()->isInIdentityMap($offer) ? "yes":"no"; //result: no
一种解决方案可以是: $offer = $this->em->merge($offer);
但这似乎不是最好的。我希望我的 EntityManager 能够感知存储在会话中的实体对象,而无需每次都告诉它。 有什么想法吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以通过将任何实体的所有属性和关系从私有设置为受保护来序列化任何实体。
即使您已将所有属性设置为受保护,您也可能会遇到 symfony2 的常见问题:您必须重新生成已更改的那些实体的代理。为此,只需清除缓存即可。对于开发环境:
app/console cache:clear
即使“它包含许多外来对象,甚至外来实体的 ArrayCollections”,正如您所说,它也可以工作。
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.
不建议序列化实体,正如您在 Doctrine 中看到的那样-文档。您应该实现 Serialized-interface 并手动序列化/反序列化实体数据。
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.
您可以通过重写 __sleep 方法来排除不必要的字段:
You can exclude unnesseary fields by overridding __sleep method: