将SecurityContext注入Symfony2中的监听器prePersist或preUpdate以获取createBy或updatedBy中的User会导致循环引用错误
我设置了一个侦听器类,在其中我将在任何 prePersist 学说上设置 Ownerid 列。我的 services.yml 文件看起来像这样......
services:
my.listener:
class: App\SharedBundle\Listener\EntityListener
arguments: ["@security.context"]
tags:
- { name: doctrine.event_listener, event: prePersist }
我的类看起来像这样......
use Doctrine\ORM\Event\LifecycleEventArgs;
use Symfony\Component\Security\Core\SecurityContextInterface;
class EntityListener
{
protected $securityContext;
public function __construct(SecurityContextInterface $securityContext)
{
$this->securityContext = $securityContext;
}
/**
*
* @param LifecycleEventArgs $args
*/
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$entityManager = $args->getEntityManager();
$entity->setCreatedby();
}
}
结果是以下错误。
ServiceCircularReferenceException:检测到服务“doctrine.orm.default_entity_manager”的循环引用,路径:“doctrine.orm.default_entity_manager -> Doctrine.dbal.default_connection -> my.listener -> security.context -> security .authentication.manager -> fos_user.user_manager”。
我的假设是安全上下文已经被注入到链中的某个位置,但我不知道如何访问它。有什么想法吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我遇到了类似的问题,唯一的解决方法是在构造函数中传递整个容器(
参数:['@service_container']
)。I had similar problems and the only workaround was to pass the whole container in the constructor (
arguments: ['@service_container']
).从 Symfony 2.6 开始,这个问题应该得到解决。拉取请求刚刚被主服务器接受。您的问题已在此处描述。
https://github.com/symfony/symfony/pull/11690
自 Symfony 起2.6,您可以将
security.token_storage
注入您的侦听器。此服务将包含SecurityContext
在 <=2.5 中使用的令牌。在 3.0 中,此服务将完全取代SecurityContext::getToken()
。您可以在此处查看基本更改列表:http://symfony.com/blog/new-in-symfony-2-6-security-component-improvements#deprecated-the-security-context-service2.6 中的用法示例:
您的配置:
您的监听器
对于一个不错的 create_by 示例,您可以使用 https://github.com/hostnet/entity-blamable-component/blob/master/src/Listener/BlamableListener.php 获取灵感。它使用 hostnet/entity-tracker-component 提供一个特殊事件,当您的请求期间实体发生更改时会触发该事件。 Symfony2 中还有一个用于配置此功能的捆绑包
As of Symfony 2.6 this issue should be fixed. A pull request has just been accepted into the master. Your problem is described in here.
https://github.com/symfony/symfony/pull/11690
As of Symfony 2.6, you can inject the
security.token_storage
into your listener. This service will contain the token as used by theSecurityContext
in <=2.5. In 3.0 this service will replace theSecurityContext::getToken()
altogether. You can see a basic change list here: http://symfony.com/blog/new-in-symfony-2-6-security-component-improvements#deprecated-the-security-context-serviceExample usage in 2.6:
Your configuration:
Your Listener
For a nice created_by example, you can use https://github.com/hostnet/entity-blamable-component/blob/master/src/Listener/BlamableListener.php for inspiration. It uses the hostnet/entity-tracker-component which provides a special event that is fired when an entity is changed during your request. There's also a bundle to configure this in Symfony2
该线程中已经有一个很好的答案,但一切都发生了变化。现在 Doctrine 中有实体监听器类:
http:// docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#entity-listeners-class
因此,您可以向实体添加注释,例如:
并创建像这样的类:
您还应该在
services.yml
中定义此侦听器,如下所示:There's a great answer already in this thread but everything changes. Now there're entity listeners classes in Doctrine:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#entity-listeners-class
So you can add an annotation to your entity like:
And create a class like this:
Also you should define this listener in
services.yml
like that:我使用教义配置文件来设置
preUpdate
或prePersist
方法:并且这些方法是在实体中声明的,这样您就不需要侦听器,并且如果您需要更通用的方法,您可以创建一个 BaseEntity 来保留该方法并从中扩展其他实体。希望有帮助!
I use the doctrine config files to set
preUpdate
orprePersist
methods:And the methods are declared in the entity, this way you don't need a listener and if you need a more general method you can make a BaseEntity to keep that method and extend the other entites from that. Hope it helps!
Symfony 6.2.4
将其添加到您的实体中:
将其添加到您的 services.yaml 中:
然后您可以执行此操作:
希望它有帮助。
Symfony 6.2.4
Add this in your Entity :
Add this in your services.yaml:
Then you can do this :
Hope it helps.