Symfony ManyToOne 关系更改类型
Posted
技术标签:
【中文标题】Symfony ManyToOne 关系更改类型【英文标题】:Symfony ManyToOne relation change type 【发布时间】:2021-03-10 11:24:21 【问题描述】:我有 2 个实体,其中 1 个由 Symfony 管理,其他则不是
不受 Symfony 管理的实体
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* User
*
* @ORM\Table(name="p_user")
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
*/
class User
/**
* @var int
*
* @ORM\Column(name="user_id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var Permission
*
* @ORM\ManyToOne(targetEntity="Permission", inversedBy="user", cascade="persist", "remove")
* @ORM\JoinColumn(name="permission_id", referencedColumnName="permission_id", onDelete="CASCADE")
*/
private $permission;
Symfony 管理的实体
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* Permission
*
* @ORM\Table(name="p_permission")
* @ORM\Entity(repositoryClass="App\Repository\PermissionRepository")
*/
class Permission
/**
* @var int
*
* @ORM\Column(name="permission_id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var ArrayCollection
*
* @ORM\OneToMany(targetEntity="User", mappedBy="permission", cascade="persist", "remove", orphanRemoval=true)
*/
private $user;
我需要保存User
实体但permission
不能为空,当没有关系时,值设置为0。
经过我的研究,我发现User::permission
接收类型为Permission::id
,但我希望User::permission
类型为nullidentity
PS: Null\IdentityType
namespace App\DBAL\Types\Null;
use Doctrine\DBAL\Types\IntegerType as DeafaultType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
class IdentityType extends DeafaultType
const NULLIDENTITY = 'nullidentity';
public function getName()
return self::NULLIDENTITY;
public function convertToDatabaseValue($value, AbstractPlatform $platform)
// dd($this);
return $value === null? 0: (int)$value;
public function convertTophpValue($value, AbstractPlatform $platform)
return $value === 0? null: (int)$value;
【问题讨论】:
【参考方案1】:在 symfony 中,验证实体的最佳实践是 Doctrine Event Subscribers。
您可以创建一个订阅者并检查、更改、删除、插入或运行您喜欢的代码。您有事件而不是触发持久化、更新或刷新。
对于您的问题,只需验证实体并根据需要进行更改。
编辑
根据要求添加一个示例。
首先你必须在 service.yaml 中注册它
App\EventSubscribers\EntitySubscriber:
tags:
- name: doctrine.event_subscriber, connection: default
然后创建一个这样的类
class EntitySubscriber implements EventSubscriber
public function getSubscribedEvents()
return [
Events::prePersist
];
public function prePersist(LifecycleEventArgs $args)
/*Continue for other entities or add the user entity in the if statement*/
if (!$args->getObject() instanceof Permission)
return;
/*Do what you need here, use the $args for more options*/
您可以找到所有活动here
【讨论】:
有例子吗?因为我这样做但不明白如何实现。@ORM\HasLifecycleCallbacks()
、@ORM\PrePersist()
和 @ORM\PreUpdate()
查看我的编辑并在实体之外尝试。在那里,您可以在construct() 中插入您想要的所有类,并将其添加到您想要检查的所有实体中。提示:尝试为小型作业创建特定的订阅者,因为它们都同时运行并且在调试中很难找到。
它对我帮助不大,因为我无法设置 $this->permission = 0,它的类型错误
正如我在评论中所建议的,您需要使用 $args 变量来获取当前实体 $entity=$args->getObject();然后改变它 $enitity->setPermision(0);或 $entity->permission =0;或调用另一个函数/类。以上是关于Symfony ManyToOne 关系更改类型的主要内容,如果未能解决你的问题,请参考以下文章
Doctrine symfony使用OneToMany删除实体 - ManyToOne关系
Symfony 5 easyadmin 3 与 ManyToOne 关系的实体 - 不保存在“多”端
Doctrine ManyToOne 关系 - 在“设置”时自动删除