Solucionado (ver solução)
Solucionado
(ver solução)
8
respostas

Erro ao criar o próprio repository

Bom dia galera, tudo bom?

Quando fui rodar o código, apareceu este erro. Alguém poderia me ajudar?

Fatal error: Uncaught Doctrine\ORM\Query\QueryException: SELECT aluno, telefones, cursos FROM Alura\Doctrine\Repositorio\Aluno aluno JOIN aluno.telefones telefones JOIN aluno.cursos cursos in /Volumes/Seagate/arquivos/cursos/alura/orm/projeto/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php:43

Arquivo 'relatorio-cursos-por-aluno-repositorio'

<?php

use Alura\Doctrine\Entity\Aluno;
use Alura\Doctrine\Entity\Telefone;
use Alura\Doctrine\Helper\EntityManagerFactory;
use Doctrine\DBAL\Logging\DebugStack;

require_once __DIR__ . "/../vendor/autoload.php";

$entityManagerFactory = new EntityManagerFactory();
$entityManager = $entityManagerFactory->getEntityManager();
$alunosRepository = $entityManager->getRepository(Aluno::class);

$debugStack = new DebugStack();
$entityManager->getConfiguration()->setSQLLogger($debugStack);

/** @var Aluno[] $alunos */
$alunos = $alunosRepository->buscarCursosPorAluno();

foreach ($alunos as $aluno) {
    $telefones = $aluno->getTelefones()
        ->map(function (Telefone $telefone) {
            return $telefone->getNumero();
        })
        ->toArray();

    echo "ID       : {$aluno->getId()}\n";
    echo "Nome     : {$aluno->getNome()}\n";
    echo "Telefones: " . implode(", ", $telefones) . "\n";

    $cursos = $aluno->getCursos();

    foreach ($cursos as $curso) {
        echo "\tID curso     : {$curso->getId()}\n";
        echo "\tNome do curso: {$curso->getNome()}\n";
        echo "\n";
    }

    echo "\n";
}

echo "\n";

foreach ($debugStack->queries as $queryInfo) {
    echo $queryInfo['sql'] . "\n";
}
8 respostas

Olá, Leonardo. Pela sua mensagem de erro, no seu repositório você não importou a classe Aluno. :-)

Bom dia professor. Mas na classe do repositório, percebi que não é usado a classe Aluno. Mesmo assim, será necessário importar a classe Aluno na classe do repositório?

Obrigado pela ajuda!

Classe do repositório:

<?php

namespace Alura\Doctrine\Repositorio;

use Doctrine\ORM\EntityRepository;

class RepositorioAluno extends EntityRepository
{
    public function buscarCursosPorAluno()
    {
        $instrucao = $this->createQueryBuilder('a')
            ->join('a.telefones', 't')
            ->join('a.cursos', 'c')
            ->addSelect('t')
            ->addSelect('c')
            ->getQuery();

        return $instrucao->getResult();
    }
}

Opa. Me mostra o conteúdo da sua classe aluno

Classe 'Aluno':

<?php

namespace Alura\Doctrine\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

/**
 * @Entity(repositoryClass="Alura\Doctrine\Repositorio\RepositorioAluno")
 */
class Aluno
{
    /**
     * @Id
     * @GeneratedValue
     * @Column (type="integer")
     */
    private $id;

    /**
     * @Column (type="string")
     */
    private $nome;

    /**
     * @OneToMany(targetEntity="Telefone", mappedBy="aluno", cascade={"remove", "persist"}, fetch="EAGER")
     */
    private $telefones;

    /**
     * @ManyToMany(targetEntity="Curso", mappedBy="alunos")
     */
    private $cursos;

    public function __construct()
    {
        $this->telefones = new ArrayCollection();
        $this->cursos = new ArrayCollection();
    }

    public function getId(): int
    {
        return $this->id;
    }

    public function getNome(): string
    {
        return $this->nome;
    }

    public function setNome($nome): self
    {
        $this->nome = $nome;
        return $this;
    }

    public function addTelefone(Telefone $telefone): self
    {
        $this->telefones->add($telefone);
        $telefone->setAluno($this);
        return $this;
    }

    public function getTelefones(): Collection
    {
        return $this->telefones;
    }

    public function addCursos(Curso $curso): self
    {
        if ($this->cursos->contains($curso)) {
            return $this;
        }
        $this->cursos->add($curso);
        $curso->addAluno($this);
        return $this;
    }

    /**
     * @return Curso[]
     */
    public function getCursos(): Collection
    {
        return $this->cursos;
    }
}

Leonardo, batendo o olho parece tudo certo. Você pode compartilhar seu projeto no GitHub pra eu rodar aqui e depurar?

solução!

Consegui resolver meu erro. Verificando os registros que estavam cadastrados dentro de cada tabela do banco de dados, percebi que a tabela 'Telefones' não tinha nenhum registro cadastrado, então, por isso que não retornava nada no terminal. Então, alterei a query do QueryBuilder(), na classe do repositório do aluno, colocando o 'leftJoin()', no lugar do 'join()' e deu certo.

Segue o código fonte da classe:

<?php

namespace Alura\Doctrine\Repositorio;

use Doctrine\ORM\EntityRepository;

class RepositorioAluno extends EntityRepository
{
    public function buscarCursosPorAluno()
    {
        $instrucao = $this->createQueryBuilder('a')
            ->leftJoin('a.telefones', 't')
            ->join('a.cursos', 'c')
            ->addSelect('t')
            ->addSelect('c')
            ->getQuery();

        return $instrucao->getResult();
    }
}

Nossa, muito estranho. A exceção lançada não tem nada a ver com o erro real. Na exceção o namespace da classe aluno apareceu errado (Alura\Doctrine\Repositorio\Aluno). Por isso pensei que era um problema no mapeamento ou algo do tipo...

Bom, que bom que conseguiu resolver. :-D