5
respostas

Repositório com Doctrine

Foi lançado o desafio para implementarmos um repositório com o Doctrine.

Fiz a Criação de uma fábrica do EntityManager que apontava para os mapeamentos das entidades em XML, conforme o proposto. Entendi que essa sugestão era devido não termos nenhuma associação das classes do domínio com a implementação da infraestrutura.

Mas quando fui criar testes para esse repositório, descobri que a minha infraestrutura estava afetando meu domínio... Em Aluno foi definido que ele iria possuir uma lista de telefones, logo uma array no PHP. Porém ao utilizar o Doctrine, obtive um erro pois ele tentava colocar um objeto do tipo PersistentCollection em uma propriedade do tipo array, no caso isso sera os telefones.

E isso faz sentido, quando se trata de coleções, o Doctrine utiliza suas próprias classes para representar. Mas como meu domínio deve estar a parte da infraestrutura, estou utilizando a array do PHP para representar listas.

Como estou utilizando já o PHP 8, estou tipando minhas propriedades, logo recebo esses erros.

Como contornar esse tipo de ação? Visto que com o Doctrine eu não faço o preenchimento dos objetos manualmente como faria com o PDO, o próprio ORM preenche tudo por Reflection.

Seria necessário fazer uma gambiarra com o uso de métodos mágicos? Ex: utilizar o __set para interceptar tal ação e transformar as coleções em arrays.

5 respostas

Oi Caique, beleza?

Retornar a lista de telefones como um array não resolve seu problema? Por exemplo: $this->telefones->toArray() ?

Diego,

O problema não é nem o retorno, mas é na busca no banco. Quando utilizado o doctrine, a partir do EntityManager eu faço a busca pelo Aluno, e o próprio Doctrine preenche os dados na entidade. Mas os telefones estão sendo armazenadas em uma array, tipada como array, e o doctrine tenta colocar um objeto PersistentCollection que é como ele representa uma coleção.

O problema todo é causado pela tipagem que temos desde o PHP 7.4.

Oi Caique,

Eu li novamente a sua pergunta com mais calma. Veja todas as respostas desse tópico criado por mim tempos atrás, possa ser que a fonte de sua dúvida tenha relação com esse assunto:

https://cursos.alura.com.br/forum/topico-colecoes-de-primeira-classe-em-entidades-146675

Diego,

Eu havia lido esse tópico, então no caso a única solução é ficar dependente da implementação de Collection do doctrine?

Eu testei... Posso criar minha própria Collection, mas ela precisa estender de uma Collection do doctrine pra funcionar pra persistência. Ai nesse caso eu precisaria sobrescrever todos os métodos de manipulação de array que ele implementa para impedir erros e adicionar o funcionamento esperado. Além de ainda precisar de uma classe Telefone que esteja mapeada no doctrine.

Pensei que pudesse ter uma solução mais simples. Nesse caso é implementado muita coisa pra ganho mínimo, já que ficarei dependente do doctrine. Vejo mais facilidade utilizar diretamente as collections fornecidas por ele e aceitar que em uma necessidade de mudanças, reimplemento conforme a necessidade.

Então Caique,

O que eu interpretei é que não precisamos ser 100% puristas no conceito, igual aquele ditado: toda regra há exceções.

Você não precisa criar sua própria Collection, pode usar a interface Collection do Doctrine e o seu ArrayCollection, observe o que Vinicius respondeu lá: uma coleção de telefones é sempre uma coleção de telefones, então uma dependência externa nessa ocasião não irá atrapalhar o seu domínio. Imagine também que está usando a Collection do Doctrine para contornar uma "falha" da linguagem que não tem um bom suporte nativo para coleções e que de quebra já ajuda com seu ORM.

Na verdade, na verdade... até acho que dá sim para você ter um array normal do PHP para armazenar os telefones, mas quando for usar o Doctrine você terá bem mais trabalho por que terá que fazer uso de um ResultSetMapping, mapeando um Aluno e depois um array de Telefones para a propriedade telefones do Aluno. Mas se isso realmente funcionar é muito trabalho para nenhuma vantagem prática.