Symfony 6:同一关联对象仅首次序列化Blob字段正常,后续为空
同一用户实体多次序列化时Blob字段仅首次返回有效值
实体定义
Post 实体
#[ORM\Entity(repositoryClass: Post::class)] class Post { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[ORM\Column(length: 255)] private ?string $body = null; #[ORM\ManyToOne(inversedBy: 'post')] private ?User $user = null; }
User 实体
#[ORM\Entity(repositoryClass: User::class)] #[UniqueEntity(fields: ['email'], message: 'There is already an account with this email')] class User { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[ORM\Column(length: 180, unique: true)] private ?string $email = null; #[ORM\Column(type: Types::BLOB, nullable: true)] private $summary = null; #[ORM\OneToMany(mappedBy: 'posts', targetEntity: Post::class)] private Collection $posts; }
二者为一对多关联:一个用户可拥有多篇帖子,一篇帖子仅属于一个用户。
序列化处理与问题表现
User::$summary是数据库Blob类型,因此实现了StreamNormalizer将PHP流资源转为字符串:
class StreamNormalizer implements NormalizerInterface { public function normalize($topic, string $format = null, array $context = []) { $data = stream_get_contents($topic); return $data; } public function supportsNormalization($data, string $format = null, array $context = []): bool { return is_resource($data); } }
Post控制器的feed路由逻辑:
#[Route('/feed', name: 'app_post_feed', methods: 'GET')] public function feed(EntityManagerInterface $entityManager): Response { $posts = $entityManager->getRepository(Post::class)->findAll(); return $this->json($posts); }
当同一用户发布多篇帖子时,JSON响应中仅第一篇帖子关联的用户summary有值,后续出现的同一用户对象的summary为空:
[ { "id": 1, "user": { "id": 1, "summary": "This is a summary", "email": "test@example.com", "userIdentifier": "test@example.com", "verified": false } }, { "id": 2, "user": { "id": 1, "summary": "", "email": "test@example.com", "userIdentifier": "test@example.com", "verified": false } } ]
猜测这是序列化组件为避免重复序列化同一对象的优化行为,但预期同一实体的所有实例数据应一致。
已尝试的无效解决方案
- 调整Normalizer尝试处理非资源类型:
class StreamNormalizer implements NormalizerInterface { public function normalize($topic, string $format = null, array $context = []) { $data = is_resource($topic) ? stream_get_contents($topic) : $topic; return $data; } public function supportsNormalization($data, string $format = null, array $context = []): bool { return is_resource($data); } }
- 修改User实体的getter方法:
public function getSummary() { return is_resource($this->summary) ? stream_get_contents($this->summary) : $this->summary; }
以上两种调整均未解决问题,求问如何让重复出现的同一实体对象返回一致的序列化结果?
内容的提问来源于stack exchange,提问作者Alex Carter
相关产品推荐
相关产品推荐

