2012-10-05 12 views
8

Ho un problema con serializzazione di entità con molte relazioni utilizzando gruppi. Ho un problema con la serializzazione di entità correlate in questo modo.Gruppi di serializzazione JMSSerializerBundle in entità con relazioni

Diciamo che ho due entità: Prodotto e Elemento correlato.

/** 
* 
* @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; 

    ... 

} 

Elemento entità ha una struttura simile:

/** 
* 
* @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; 

    ... 
} 

mio problema è che quando sto serializzazione del prodotto con entità del gruppo 'dettagli' Voglio serializzare solo id di elementi, ma come vedete entità ha definito gli stessi gruppi come Prodotto (nel caso in cui avessi bisogno di dettagli dell'oggetto elemento) perché voglio avere gruppi unificati su tutte le mie entità e impedire di creare centinaia di gruppi come 'product_details', 'element_details' e così via.

C'è un modo per cambiare seriamente il gruppo di serializzazione quando visito una relazione o qualcosa del genere? Forse un handler o qualcosa del genere?

Saluti e grazie per tutto l'aiuto

+2

Ho usato il product_list' ecc soluzione 'product_detail' /', e è stato molto carino, perché hai sempre il pieno controllo di ciò che è serializzato. Il rovescio della medaglia è ovviamente il modo prolisso il codice ottiene durante la serializzazione più classi ... mi piacerebbe anche usare 'xxx_partial' /' xxx_full', invece di 'xxx_list' /' xxx_details'. – AdrienBrault

+1

@AdrienBrault Grazie per la risposta.Sì, sto usando questa soluzione in questo momento ma ha uno svantaggio - che i gruppi devono essere definiti in ogni entità correlata nel caso in cui io abbia molte molte entità in uso comuni dizionari gruppi di entità l'annotazione sarà enorme – mrMantir

+1

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

risposta

7

Purtroppo, non si può davvero (ma continuate a leggere ;-)), beh almeno non senza modifiche alla libreria serializzatore. Il colpevole è che l'elenco dei gruppi è stato risolto in un GroupExclusionStrategy (a cui fa riferimento lo Context) al momento dell'avvio del processo di serializzazione. Esiste effettivamente un'asserzione all'interno del codice che impedisce la modifica della strategia di esclusione una volta eseguita la (de-) serializzazione.

Ma come accade, ho avuto lo stesso identico problema in un mio progetto come bene, e ho inciso le modifiche necessarie nel codice serializzatore. Ho pulito un po 'il codice e l'ho caricato su Github (https://github.com/andreasferber/serializer/tree/recursion-groups).

Si aggiunge nuovi metadati proprietà con cui è possibile aggiungere, rimuovere o sovrascrivere i gruppi discendendo nel sotto-oggetti. Con annotazioni sembra che questo:

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

Si dovrebbe essere in grado di utilizzare i metadati XML o Yaml pure, tuttavia questo non è testato dal momento che non li uso e non l'ho ancora aggiunto casi di test. Dai un'occhiata alla documentazione di riferimento. Dal momento che non ho ancora fatto nessuna ottimizzazione, se le tue entità sono davvero grandi e profondamente annidate, potrebbe avere un notevole impatto sulle prestazioni.

Per favore fatemi sapere se trovate questo utile, o se avete qualche suggerimento, perché se questo non è solo necessario da parte mia, aggiungerò dei test e proveremo a inviarlo a monte.

+0

a prima vista sembra davvero buono, lo proverò oggi o domani –

+0

beh, IMHO che forking il serializzatore ufficiale shouldn ' essere la migliore soluzione "generale" per questo problema comune, ma non aver ancora trovato una soluzione sufficientemente buona, a parte l'uso della soluzione 'VirtualProperty' –

+2

Si dovrebbe prendere in considerazione la richiesta pull a monte – Szpadel

0

Una soluzione per questo è in realtà descritta nel official documentation.

Detto questo la soluzione proposta da @aferber sembra meglio su molti punti: più facili da mantenere, meno prolissa, più flessibile ...

+0

per qualche stupido motivo che la soluzione nella documentazione ufficiale non funziona –

Problemi correlati