[英]How to handle recursive objects with JMS Serializer
我正在尝试序列化和反序列化Doctrine对象图。
结构非常复杂,但这个例子总结了我的问题:
有一个与Employee
具有OneToMany关系的Company
实体。
Employee
实体与Company
具有ManyToOne关系。
这序列化如下:
{
"company": {
"name": "MegaCorp",
"employees": [{
"name": "John Doe",
"company": null
}]
}
}
因此, null
S中的参考Employee
的父Company
。 对于序列化,这没关系。 但是现在当我反序列化这个json时,我在Employee
对象中得到一个null
Company
。 我想(和期望)是获得正确的引用,父Company
。
这是否可以使用JMS序列化器,如果是这样,它怎么做?
如果不可能,那么什么是一个好的解决方法? 请记住,它是一个大图,我不想手动执行。
不幸的是,在反序列化时,序列化程序无法知道对象是相同的还是实际上是同一个对象。 即使你可以递归地嵌套它们。
但是,在将@Accessor
注释与某些业务逻辑相结合时,您可以获得所需的结果。 所以离开你的榜样:
class Company {
/**
* @Accessor(setter="addEmployees")
*/
private $employees;
public function addEmployee(Employee $employee)
{
if (!$this->employees->contains($employee)) {
$this->employees[] = $employee;
$employee->setCompany($this);
}
}
public function addEmployees($employees)
{
foreach ($employees as $employee) {
$this->addEmployee($employee);
}
}
}
class Employee {
/**
* @Accessor(setter="setCompany")
*/
private $company;
public setCompany(Company $company = null)
{
$this->company = $company;
if ($company) {
$company->addEmployee($this);
}
}
}
我认为这比使用@PostDeserialize
更自然,因为您的代码中可能已经有了一些这样的方法。 此外,它以两种方式确保合同,因此如果您从Employee
开始,您将获得相同的结果。
在反序列化对象时手动设置引用是什么? 像这样的东西:
class Company {
....
@PostDeserialize
public function setReferences()
{
foreach( $this->employees as $employee ){
$employee->setCompany( $this );
}
}
}
保持JSON实体尽可能简单是一种很好的做法! 如果您必须处理这类问题,那么重新考虑您的数据模型的时刻到了!
另外,您是否考虑过使用HATEOAS(超媒体作为应用程序状态的引擎)是一个原则,应该使用超文本链接来创建更好的API导航。 看起来像这样:
{
"id": 711,
"manufacturer": "bmw",
"model": "X5",
"seats": 5,
"drivers": [
{
"id": "23",
"name": "Stefan Jauker",
"links": [
{
"rel": "self",
"href": "/api/v1/drivers/23"
}
]
}
]
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.