Sto sviluppando un'applicazione utilizzando Symfony 2 che è strutturato in modo tale che un fascio "Core" definisce entità, relazioni e campi. Altri bundle sono quindi in grado di specializzare la funzionalità di base per ereditarietà, i cosiddetti bundle "figlio".
Le annotazioni di Doctrine 2 sono state utilizzate per definire un'entità core denominata "Pacchetto". Un "pacchetto" collega insieme un progetto architettonico e un pezzo di terra, essenzialmente un pacchetto casa-terra. Ho ridisegnato gli esempi a una forma più semplice, quindi non troverete le definizioni per Land e ChildLand negli esempi seguenti, ma si può presumere che siano stati implementati in modo simile.
Aggiornamento
Secondo gli utenti sul canale #symfony di FreeNode, questo è un problema di dottrina come il comando app/console invoca semplicemente il console dottrina. Sto usando la dottrina 2.3.
Ecco un diagramma che mostra la situazione generale che causa il problema, che dovrebbe aiutare a visualizzare lo scenario:
(imgur link to full-size image)
Inoltre, ecco un link per un bug report sulle issue tracker di dottrina : http://www.doctrine-project.org/jira/browse/DDC-2605
Update 2 - più dettagliate ERD
Th La struttura delle relazioni tra entità è stata messa in discussione, quindi di seguito è riportato un esempio migliore della struttura dei dati che stiamo implementando.
Il requisito principale è di nuovo disporre di classi principali che forniscono un insieme condiviso di entità e campi. Le lezioni secondarie nei pacchetti di società estendono queste classi chiave.
Abbiamo considerato l'EAV a lungo, ma con questo approccio passeremo molto più tempo a creare una piattaforma e gli strumenti per gestire i dati EAV piuttosto che soddisfare i requisiti aziendali attuali, non saremo in grado di utilizzare la dottrina per gestire le entità come saranno definite nel database, ecc.
Con il passare del tempo e giungendo a comprendere meglio questo problema, sembra che l'unico problema sia con i getter e i setter generati dallo strumento CLI di doctrine che si interrompe i contratti tipo di suggerimento come indicato di seguito. Questa struttura funziona perfettamente quando questi problemi vengono corretti manualmente.
(imgur link to full-size image)
Generazione Entità con CLI Tool
Così, inizialmente ho usato lo strumento da riga di comando ...
> app/console doctrine:generate:entity
...per generare gli stub entità con mappature dei campi di base, poi ha aggiunto manualmente il rapporto alla terra (come lo strumento non sembra supportare i rapporti):
Questo è il codice risultante:
nucleo entità pacchetto: http://pastebin.com/3ujPT1mJ
bambino entità pacchetto: http://pastebin.com/sjAB0XJ2
Generare getter e setter
Avanti, genero i getter e setter eseguendo:
> app/console doctrine:generate:entities CompanyCoreBundle
> app/console doctrine:generate:entities CompanyChildBundle
che modifica automaticamente i core e di entità bambino definizioni:
nucleo entità pacchetto: http://pastebin.com/kfQRxcnm
bambino entità pacchetto: http://pastebin.com/UdiPP9xX
il problema!
Così, il nocciolo della questione è questo: Se si confronta la funzione setLand nel bundle Core e bambino, è possibile vedere le dichiarazioni sono diverse:
public function setLand(\Company\CoreBundle\Entity\Land $land = null)
public function setLand(\Company\ChildBundle\Entity\ChildLand $land = null)
errori :(
Purtroppo, i diversi indizi tipo causano errori PHP severe a verificarsi, ad esempio:
PHP Fatal error: Class 'Symfony\Component\Debug\Exception\ContextErrorException' not found in ... Company/ChildBundle/Entity/ChildPackage.php on line ...
E
Runtime Notice: Declaration of ... should be compatible with ... in ... line ...
La causa degli errori
Dopo aver fatto qualche ricerca sul motivo per cui questo è stato un problema, ho letto in diversi luoghi che cambiano tipo di hinting in sottoclassi pause tipo alludono contratti (vedi questo post: Is there a way to redefine a type hint to a descendant class when extending an abstract class?).
Opzioni?
ci sono alcune opzioni ovvi ma meno-che-ideale:
- posso sopprimere le comunicazioni severe abbastanza facilmente, ma il mio responsabile dello sviluppo baulks alla prospettiva di dover creare eccezioni fiocco di neve nei nostri processi di CI.
- Posso modificare manualmente il codice che la dottrina genera per rimuovere tutti i tipi di suggerimenti, o per garantire che gli hint del tipo di classe figlio siano gli stessi delle classi genitore. Fare questo fa funzionare il codice, ma posso vederlo essere noioso a meno che non scrivo alcuni script per gestirlo per me.
- Non posso semplicemente usare gli strumenti da riga di comando e creare manualmente le mie entità e sottounità manualmente. Preferirei essere in grado di automatizzare questo con script :(
La mia domanda !!!(finalmente)
La mia domanda è, è possibile utilizzare gli strumenti della riga di comando per fare ciò che sto cercando di fare qui? Idealmente, mi piacerebbe essere in grado di eseguire i comandi della console doctrine per generare stub di entità e getter e setter senza l'intervento manuale per correggere i suggerimenti di tipo nelle sottoclassi. Se questo non è facilmente realizzabile, qual è l'opzione migliore?
Gratitudine
Grazie!
Sarebbe questo aiuto? http://symfony.com/doc/current/cookbook/doctrine/resolve_target_entity.html – jmlnik
Non senza ripensare drasticamente al mio approccio. Innanzitutto, avrei bisogno di un'interfaccia per ogni relazione. La seconda e probabilmente la ragione principale è che secondo la documentazione "il ResolveTargetEntityListener può solo cambiare la destinazione in un singolo oggetto", mentre dovrò estendere le funzionalità di base su molti bambini, quindi avrò "XPackage", "YPackage" ecc. Grazie per la risposta, però, non ero a conoscenza di questa funzionalità e la considererò sicuramente per gli scenari futuri. –
Stai chiedendo una parte di codice in cui puoi vedere che la dottrina non è in grado di gestire la situazione in cui la classe ereditata ha una proprietà di relazione sovrascritta? –