2012-10-05 23 views
8

Tengo un problema con la serialización de entidades con muchas relaciones usando grupos. Tengo un problema con la serialización de entidades relacionadas de esta manera.JMSSerializerBundle grupos de serialización en entidades con relaciones

Digamos que tengo dos entidades: Producto y Elemento relacionado.

/** 
* 
* @Serializer\ExclusionPolicy("none") 
*/ 
class Product { 

    /** 
    * Primary key 
    * @var integer $id 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    * 
    * @Serializer\Groups({"list","details"}) 
    * @Serializer\Type("integer") 
    */ 
    protected $id; 

    /** 
    * @Serializer\Groups({"list","details"}) 
    * @Serializer\Type("string") 
    */ 
    protected $name; 

    /** 
    * @ORM\Column(name="description", type="string", length=4096, nullable=true) 
    * 
    * @Serializer\Groups({"details"}) 
    * @Serializer\Type("string") 
    */ 
    protected $description; 

    /** 
    * @var ArrayCollection 
    * 
    * @ORM\OneToMany(targetEntity="Madden\ProjectBundle\Entity\ProjectResource", mappedBy="project") 
    * @Serializer\Groups({"details"}) 
    * @Serializer\Type("ArrayCollection<Element>") 
    */ 
    protected $details1; 

    /** 
    * Relation to project tasks 
    * @ORM\OneToMany(targetEntity="Madden\ProjectBundle\Entity\ProjectTask", mappedBy="project") 
    * @Serializer\Exclude() 
    * @Serializer\Type("ArrayCollection<Element>") 
    */ 
    protected $details2; 

    ... 

} 

entidad Element tiene una estructura similar:

/** 
* 
* @Serializer\ExclusionPolicy("none") 
*/ 
class Element { 

    /** 
    * Primary key 
    * @var integer $id 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    * 
    * @Serializer\Groups({"list","details"}) 
    * @Serializer\Type("integer") 
    */ 
    protected $id; 

    /** 
    * @Serializer\Groups({"list","details"}) 
    * @Serializer\Type("string") 
    */ 
    protected $name; 

    /** 
    * @ORM\Column(name="description", type="string", length=4096, nullable=true) 
    * 
    * @Serializer\Groups({"details"}) 
    * @Serializer\Type("string") 
    */ 
    protected $description; 

    ... 
} 

Mi problema es que cuando estoy serialización del producto con entidad del grupo 'detalles' quiero serializar sólo identificadores de elementos, pero como ves entidad ha definido los mismos grupos como Producto (en caso de que necesite detalles del objeto del elemento) porque quiero tener grupos unificados en todas mis entidades y evitar hacer cientos de grupos como 'detalles del producto', 'detalles del elemento', y así sucesivamente.

¿Hay alguna manera de eventualmente cambiar el grupo de serialización cuando visito una relación o algo así? ¿Manipulador tal vez o algo así?

Un saludo y gracias por cualquier ayuda

+2

He utilizado el 'product_detail' /' solución product_list' etc, y fue muy agradable, porque siempre tienes control total de lo que se serializa. La desventaja es obviamente cuán detallado es el código al serializar múltiples clases ... También usaría 'xxx_partial' /' xxx_full', en lugar de 'xxx_list' /' xxx_details'. – AdrienBrault

+1

@AdrienBrault Gracias por responder.Sí, estoy usando esa solución en este momento, pero tiene una desventaja: los grupos deben definirse en cada entidad relacionada en caso de que tenga muchas entidades en común. La anotación de los grupos de entidades de diccionarios será enorme – mrMantir

+1

Eso es sobre [VirtualProperty] (http://jmsyst.com/libs/serializer/master/reference/annotations#virtualproperty)? –

Respuesta

7

Por desgracia, realmente no se puede (pero sigue leyendo ;-)), bueno al menos no sin cambios en la biblioteca serializador. El culpable es que la lista de grupos se corrige dentro de un GroupExclusionStrategy (al que hace referencia el Context) en el momento en que inicia el proceso de serialización. De hecho, hay una afirmación dentro del código que impide la modificación de la estrategia de exclusión una vez que se ejecuta la (des) serialización.

Pero, como sucede, también tuve exactamente el mismo problema en un proyecto mío, y pirateé los cambios necesarios en el código del serializador. Limpié un poco el código y lo cargué en Github (https://github.com/andreasferber/serializer/tree/recursion-groups).

Agrega nuevos metadatos de propiedades con los cuales puede agregar, eliminar o anular los grupos al descender a subobjetos. Con anotaciones se ve así:

/** 
* @Serializer\RecursionGroups(set={"foo", "bar"}, add={"baz"}, remove={"Default"}) 
*/ 
private $myProperty; 

Usted debe ser capaz de utilizar los metadatos XML o Yaml así, sin embargo, esto no se ha probado ya que no los uso y no he añadido los casos de prueba todavía. Eche un vistazo a la documentación de referencia. Dado que aún no he hecho ninguna optimización, si tus entidades son realmente grandes y están profundamente anidadas, podría tener un impacto notable en el rendimiento.

Háganme saber si le resulta útil, o si tiene alguna sugerencia, porque si no solo la necesito, añadiré algunas pruebas e intentaré enviarla en sentido ascendente.

+0

a primera vista, parece realmente bueno, lo intentaré hoy o mañana –

+0

, en mi humilde opinión bifurcar el serializador oficial shouldn ' t es la mejor solución "general" para este problema común, pero aún no se ha encontrado una solución lo suficientemente buena, aparte de usar la solución 'VirtualProperty' –

+2

Debería considerar la solicitud de extracción en sentido ascendente – Szpadel

0

Una solución para esto se describe en realidad en el official documentation.

Dicho esto la solución propuesta por @aferber parece mejor en muchos puntos: más fácil de mantener, menos detallado, más flexible ...

+0

por alguna estúpida razón por la que la solución en la documentación oficial no funciona –

Cuestiones relacionadas