Symfony 4 Serializer: deserializing request and merging it with entity including relation that is not completely passed by client(symfony 4序列化程序:反序列化请求并将其与客户端未完全传递的实体(包括关系)合并)
问题描述
假设我有一个名为user的实体:
class User implements UserInterface
/**
* @ORMId()
* @ORMGeneratedValue()
* @ORMColumn(type="integer")
*/
private $id;
/**
* @ORMColumn(type="string", length=255, nullable=false)
*/
private $username;
/**
* @ORMOneToOne(targetEntity="AppEntityAddress", cascade={"persist", "remove"})
* @ORMJoinColumn(nullable=false)
*/
private $address;
地址字段与地址实体是一对一关系:
class Address
{
/**
* @ORMId()
* @ORMGeneratedValue()
* @ORMColumn(type="integer")
*/
private $id;
/**
* @ORMColumn(type="string", length=255)
*/
private $street;
/**
* @ORMColumn(type="string", length=255)
*/
private $name;
我有一个用于更新用户及其地址的控制器:
...
public function putUserSelf(Request $request)
{
$em = $this->getDoctrine()->getManager();
$user = $this->getUser();
$encoders = array(new JsonEncoder());
$normalizers = array(new ObjectNormalizer(null, null, null, new ReflectionExtractor()));
$serializer = new Serializer($normalizers, $encoders);
$user = $serializer->deserialize($request->getContent(), User::class, "json", ['deep_object_to_populate' => $user]);
$em->persist($user);
$em->flush();
理论上,我现在应该可以像这样传递json:
{
"username": "foo",
"address": {"name": "bar"}
}
更新我的实体。但问题是,我收到一个SQL错误:
An exception occurred while executing 'INSERT INTO address (street, name) VALUES (?, ?)' with params [null, "bar"]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'street' cannot be null
实体合并似乎不起作用。
推荐答案
根据docs,
当
AbstractObjectNormalizer::DEEP_OBJECT_TO_POPULATE
选项设置为true时,根OBJECT_TO_POPULATE
的现有子项将从规范化数据中更新,而不是由去规格化程序重新创建它们。[.] (强调我的)
所以您必须设置一个额外的选项,因此您的行应该是:
$user = $serializer->deserialize($request->getContent(), User::class, "json", [
'object_to_populate' => $user, // this still needs to be set, without the "deep_"
'deep_object_to_populate' => true,
]);
特定组件的源代码中有一些附加注释:
/** * Flag to tell the denormalizer to also populate existing objects on * attributes of the main object. * * Setting this to true is only useful if you also specify the root object * in OBJECT_TO_POPULATE. */ public const DEEP_OBJECT_TO_POPULATE = 'deep_object_to_populate';
来源:https://github.com/symfony/symfony/blob/d8a026bcadb46c9955beb25fc68080c54f2cbe1a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php#L82
这篇关于symfony 4序列化程序:反序列化请求并将其与客户端未完全传递的实体(包括关系)合并的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:symfony 4序列化程序:反序列化请求并将其与客户端未完全传递的实体(包括关系)合并
基础教程推荐
- 如何在 PHP 中的请求之间持久化对象 2022-01-01
- 在 Woocommerce 中根据运输方式和付款方式添加费用 2021-01-01
- WooCommerce 中选定产品类别的自定义产品价格后缀 2021-01-01
- 超薄框架REST服务两次获得输出 2022-01-01
- 在 PHP 中强制下载文件 - 在 Joomla 框架内 2022-01-01
- 在多维数组中查找最大值 2021-01-01
- mysqli_insert_id 是否有可能在高流量应用程序中返回 2021-01-01
- 通过 PHP SoapClient 请求发送原始 XML 2021-01-01
- XAMPP 服务器不加载 CSS 文件 2022-01-01
- Libpuzzle 索引数百万张图片? 2022-01-01