PHP neo4j OGM - обнаружена рекурсия
Я использую EntityManager в моем проекте. Я могу успешно читать / добавлять свои энтиты и отношения между ними в БД, но у меня есть одна проблема.
У меня есть два узла Employee и Document и связь между ними как Employee HAS Document.
php класс для Emloyee:
<?php
namespace App\Models;
use GraphAware\Neo4j\OGM\Annotations as OGM;
use \GraphAware\Neo4j\OGM\Common\Collection;
/**
*
* @OGM\Node(label="Employee")
*/
class Employee implements \JsonSerializable {
public function __construct() {
$this->documents = new Collection();
$this->addresses = new Collection();
}
/**
* Id
* @var int
* @OGM\GraphId()
*/
protected $id;
/**
* name
* @var string
*
* @OGM\Property(type="string")
*/
protected $name;
/**
* lastname
* @var string
*
* @OGM\Property(type="string")
*/
protected $lastname;
/**
* personalidnumber
* @var string
*
* @OGM\Property(type="string")
*/
protected $personalidnumber;
/**
* @var Document[]|Collection
*
* @OGM\Relationship(type="HAS", direction="OUTGOING", collection=true, mappedBy="employees", targetEntity="Document")
*/
protected $documents;
/**
* @var Address[]|Collection
*
* @OGM\Relationship(type="HAS", direction="OUTGOING", collection=true, mappedBy="employees", targetEntity="Address")
*/
protected $addresses;
public function getaddresses() {
return $this->addresses;
}
public function getdocuments(){
return $this->documents;
}
public function getname(){
return $this->name;
}
public function setname($name){
$this->name = $name;
}
function getlastname() {
return $this->lastname;
}
public function setlastname($lastname){
$this->lastname = $lastname;
}
function getpersonalidnumber() {
return $this->lastname;
}
public function setpersonalidnumber($personalidnumber){
$this->personalidnumber = $personalidnumber;
}
public function jsonSerialize() {
return [
'id' => $this->id,
'name' => $this->name,
'lastName' => $this->lastname,
'personalidnumber' => $this->personalidnumber,
'addresses' =>$this->addresses->toArray(),
'documents' =>$this->documents->toArray()
];
}
}
класс php для Document:
<?php
namespace App\Models;
use GraphAware\Neo4j\OGM\Annotations as OGM;
use GraphAware\Neo4j\OGM\Common\Collection;
/**
*
* @OGM\Node(label="Document")
*/
class Document implements \JsonSerializable{
public function __construct() {
$this->employees = new Collection();
$timezone = new \DateTimeZone('Europe/Ljubljana');
$t = microtime(true);
$micro = sprintf("%06d",($t - floor($t)) * 1000000);
$dt = new \DateTime( date('Y-m-d H:i:s.'.$micro, $t));
$dt->setTimezone($timezone);
$this->crdate = $dt->format('YmdHis.u');
$this->validfrom = $this->crdate;
}
/**
* @OGM\GraphId()
*
* @var int
*/
protected $id;
/**
* @var string
*
* @OGM\Property(type="string")
*/
protected $name;
/**
* @var string
*
* @OGM\Property(type="string")
*/
protected $uniquename;
/**
* @var string
*
* @OGM\Property(type="string")
*/
protected $path;
/**
* @var string
*
* @OGM\Property(type="string")
*/
protected $ext;
/**
* @var string
*
* @OGM\Property(type="string")
*/
protected $documentid;
/**
* @var string
*
* @OGM\Property(type="string")
*/
protected $validfrom;
/**
* @var string
*
* @OGM\Property(type="string")
*/
protected $validto;
/**
* @var string
*
* @OGM\Property(type="string")
*/
protected $crdate;
/**
* @var string
*
* @OGM\Property(type="string")
*/
protected $language;
/**
* @var string
*
* @OGM\Property(type="string")
*/
protected $type;
/**
* @var string
*
* @OGM\Property(type="string")
*/
protected $description;
/**
* @var DocEmployees[]|Collection
*
* @OGM\Relationship(type="HAS", direction="INCOMING", collection=true, mappedBy="documents", targetEntity="Employee")
*/
protected $employees;
public function getemployees() {
return $this->employees;
}
public function getid() {
return $this->id;
}
public function getname() {
return $this->name;
}
public function setname($name) {
$this->name = $name;
}
public function getuniquename() {
return $this->uniquename;
}
public function setuniquename($uniquename) {
$this->uniquename = $uniquename;
}
public function getpath() {
return $this->path;
}
public function setpath($path) {
$this->path = $path;
}
public function getext() {
return $this->ext;
}
public function setext($ext) {
$this->ext = $ext;
}
public function getdocumentid() {
return $this->documentid;
}
public function setdocumentid($documentid) {
$this->documentid = $documentid;
}
public function getvalidfrom() {
return $this->validfrom;
}
public function setvalidfrom($validfrom) {
$this->validfrom = $validfrom;
}
public function getvalidto() {
return $this->validto;
}
public function setvalidto($validto) {
$this->validto = $validto;
}
public function getlanguage() {
return $this->language;
}
public function setlanguage($language) {
$this->language = $language;
}
public function getcrdate() {
return $this->crdate;
}
public function setcrdate($crdate) {
$this->crdate = $crdate;
}
public function gettype() {
return $this->type;
}
public function settype($type) {
$this->type = $type;
}
public function getdescription() {
return $this->description;
}
public function setdescription($description) {
$this->description = $description;
}
public function getfullname(){
return $this->path.$this->uniquename;
}
public function jsonSerialize() {
return [
'id' => $this->id,
'name' => $this->name,
'uniquename' => $this->uniquename,
'path' => $this->path,
'ext' => $this->ext,
'validfrom' => $this->validfrom,
'validto' => $this->validto,
'language' => $this->language,
'crdate' => $this->crdate,
'type' => $this->type,
'description' => $this->description,
'employees' => $this->employees->toArray()
];
}
}
затем у меня есть две конечные точки API, я использую платформу Slim для REST API, в основном у меня есть два метода, которые возвращают данные.
для сотрудников:
public function getAllEmployees(){
$this->logger->info(__CLASS__.':'.__FUNCTION__);
$employeesRepository = $this->dbentity->getRepository(Employee::class);
$employees = $employeesRepository->findAll();
return $employees;
}
для документов:
public function getAllDocuments(){
$this->logger->info(__CLASS__.':'.__METHOD__);
$documentRepository = $this->dbentity->getRepository(Document::class);
$documents = $documentRepository->findAll();
return $documents;
}
Так что моя проблема в том, когда я раскомментирую
'employees' => $this->employees->toArray()
в классе Document
я получаю ошибку во время выполнения Обнаружена рекурсия
без этой строки все работает нормально.
Может ли кто-нибудь помочь мне, что мне не хватает?
1 ответ
Ошибка происходит потому, что в jsonSerialize()
документов вы включаете всех сотрудников. В jsonSerialize()
Сотрудника вы включаете все документы, поэтому вы создаете бесконечное вложение документов, которое никогда не заканчивается. При включении документов в записи Employee в ответ API необходимо пропустить сериализацию всех документов.