3

我正在尝试序列化和反序列化 Doctrine 对象图。

结构相当复杂,但这个例子总结了我的问题:

有一个Company与 具有 OneToMany 关系的实体Employee
Employee实体与 具有多对一关系Company

这被序列化如下:

{
    "company": {
        "name": "MegaCorp",
        "employees": [{
            "name": "John Doe",
            "company": null
        }]
    }
}

所以它是对父级null的引用。对于序列化,这是可以的。但是现在当我反序列化这个 json 时,我在对象中得到了一个。我想要(和期望)的是获得对 parent 的正确引用。EmployeeCompanynull CompanyEmployeeCompany

这是否可以使用 JMS 序列化程序,如果可以,怎么做?
如果不可能,有什么好的解决方法?请记住,这是一个大图,我不想手动进行。

4

3 回答 3

2

不幸的是,在反序列化时,序列化程序无法知道对象是否相同或实际上是相同的对象。即使您可以递归地嵌套它们。

但是,将@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你会得到相同的结果。

于 2016-04-15T08:36:56.250 回答
0

反序列化对象后手动设置引用是什么?像这样的东西:

class Company { 

    ....

    @PostDeserialize
    public function setReferences()
    {
        foreach( $this->employees as $employee ){
            $employee->setCompany( $this );
        }
    }
}
于 2016-07-16T14:30:41.133 回答
0

保持 JSON 实体尽可能简单是一个好习惯!如果你必须处理这类问题,是时候重新考虑你的数据模型了!

另外,你有没有想过使用 HATEOAS(Hypermedia as the Engine of Application State)是一个原则,即应该使用超文本链接来创建更好的 API 导航。看起来像这样:

{
  "id": 711,
  "manufacturer": "bmw",
  "model": "X5",
  "seats": 5,
  "drivers": [
   {
    "id": "23",
    "name": "Stefan Jauker",
    "links": [
     {
     "rel": "self",
     "href": "/api/v1/drivers/23"
    }
   ]
  }
 ]
}
于 2017-01-20T17:00:54.420 回答