Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Doctrine][JMS] ManyToMany + self referencing

7 juin 2019 à 12:11:20

Bonjour à tous

J'ai un soucis de sérialisation avec une table qui possède une jointure ManyToMany avec elle même.

J'ai la structure suivante :

CREATE TABLE table1 (
  id INT AUTO_INCREMENT,
  label VARCHAR(255),
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
);

CREATE TABLE table2 (
  id INT AUTO_INCREMENT,
  parent_id INT,
  child_id INT,
  position INT,
  PRIMARY KEY(id)
);

ALTER TABLE table2 ADD FOREIGN KEY (parent_id) REFERENCES table1 (id);

ALTER TABLE table2 ADD FOREIGN KEY (child_id) REFERENCES table1 (id);

INSERT INTO table1 (id, label) VALUES
(1, "LABEL 1"),
(2, "LABEL 2");

INSERT INTO table2 (id, parent_id, child_id, position) VALUES
(1, 1, 1, 0),
(2, 1, 2, 1);


Et voici les entités Doctrine correspondantes (j'ai omis les getters / setters pour limiter la taille) :

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;

/**
 * @ORM\Entity
 * @ORM\Table(name="table1")
 */
class Table1
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(name="id", type="integer")
     * @Serializer\Groups({"details"})
     */
    protected $id;

    /**
     * @ORM\Column(name="label", type="string")
     * @Serializer\Groups({"details"})
     */
    protected $label;

    /**
     * @ORM\Column(name="created_at", type="datetime")
     * @Serializer\Groups({"details"})
     */
    protected $createdAt;

    /**
     * @ORM\OneToMany(targetEntity="Table2", mappedBy="parent")
     * @ORM\OrderBy({"position": "ASC"})
     * @Serializer\Groups({"details"})
     */
    protected $associations;
}
<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;

/**
 * @ORM\Entity
 * @ORM\Table(name="table2")
 */
class Table2
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(name="id", type="integer")
     * @Serializer\Groups({"details"})
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Table1")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
     */
    protected $parent;

    /**
     * @ORM\ManyToOne(targetEntity="Table1")
     * @ORM\JoinColumn(name="child_id", referencedColumnName="id")
     * @Serializer\Groups({"details"})
     * @Serializer\MaxDepth(1)
     */
    protected $child;

    /**
     * @ORM\Column(name="position", type="integer")
     * @Serializer\Groups({"details"})
     */
    protected $position;
}

Je récupère ensuite l'enregistrement #1 de ma table "table1" que je sérialise en JSON :

<?php

use App\Entity\Table1;
use JMS\Serializer\SerializationContext;

//...

$context = new SerializationContext();
$context->enableMaxDepthChecks();
$context->setGroups(['details']);

echo $serializer->serialize($em->find(Table1::class, 1), 'json', $context);


Et voici le résultat obtenu :

{
  "id":1,
  "label":"LABEL 1",
  "created_at":"2019-06-06T14:46:07+00:00",
  "associations":[
  {
    "id":1,
    "position":0
  },
  {
    "id":2,
    "child":{
      "id":2,
      "label":"LABEL 2",
      "created_at":"2019-06-06T14:46:07+00:00",
      "associations":[]
    },
    "position":1
  }
  ]
}


On remarque que dans le tableau "associations", le premier élément (qui fait référence à lui même) ne comporte pas d'élément "child" alors que le deuxième élément oui.

Sauriez vous me dire pourquoi cet élément "child" n'est pas récupéré lorsque la relation fait référence au même enregistrement ?

Merci :)

  • Partager sur Facebook
  • Partager sur Twitter
7 juin 2019 à 13:47:04

Bonjour,

Lecture diagonale rapide ... 

Tu as indiqué une profondeur de sérialisation de 1 : ligne 32 ... cela pourrait venir de là.

A+

-
Edité par monkey3d 7 juin 2019 à 13:47:15

  • Partager sur Facebook
  • Partager sur Twitter
7 juin 2019 à 14:51:15

Bonjour

Non j'ai déjà essayé de modifier cette valeur mais ça ne change rien : le premier objet du tableau "associations" (qui fait donc référence à lui même) ne possède toujours pas l'élément "child" alors que le deuxième objet, oui. 

  • Partager sur Facebook
  • Partager sur Twitter
1 juillet 2020 à 16:41:03

As-tu réussi, car j'ai le même genre de soucis ?
  • Partager sur Facebook
  • Partager sur Twitter
1 juillet 2020 à 17:03:48

Bonjour,

Déterrage

Citation des règles générales du forum :

Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.

Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre.
En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.

Au lieu de déterrer un sujet il est préférable :

  • soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
  • soit de créer un nouveau sujet décrivant votre propre contexte
  • ne pas répondre à un déterrage et le signaler à la modération

Je ferme ce sujet. En cas de désaccord, me contacter par MP.

  • Partager sur Facebook
  • Partager sur Twitter