I've been using Symfony and Doctrine for a few good years now and don't even remember using built in Doctrine methods like find, findAll, findBy and findOneBy. Instead I always created my own methods in repository class that used EntityRepository. In this example we choose composition over inheritance and adopting Dependency Inversion Principle.


Advantages



Inheritance version


We won't use this because it inherits everything you don't need! Just showing how it is done.


Entity


namespace CustomerBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity
* @ORM\Table(name="customer")
* @ORM\Entity(repositoryClass="CustomerBundle\Repository\CustomerRepository")
*/
class Customer
{
...
}

Repository


namespace CustomerBundle\Repository;

use Doctrine\ORM\EntityRepository;

class CustomerRepository extends EntityRepository
{
public function findAll()
{
return $this->createQueryBuilder('c')
->getQuery()
->getArrayResult();
}

public function findOneById($id)
{
return $this->createQueryBuilder('c')
->where('c.id = :id')
->setParameter('id', $id)
->getQuery()
->getOneOrNullResult();
}
}

services:
customer.repository.customer:
class: CustomerBundle\Repository\CustomerRepository
factory: [ "@doctrine.orm.entity_manager", getRepository ]
arguments:
- CustomerBundle\Entity\Customer

Composition version


Entity


namespace CustomerBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity
* @ORM\Table(name="customer")
*/
class Customer
{
...
}

Repository - V1


Use this version over the V2.


namespace CustomerBundle\Repository;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;

abstract class AbstractRepository
{
private $entityManager;
private $entityName;

public function __construct(EntityManagerInterface $entityManager, string $entityName)
{
$this->entityManager = $entityManager;
$this->entityName = $entityName;
}

protected function getEntityManager(): EntityManagerInterface
{
return $this->entityManager;
}

protected function getRepository(): EntityRepository
{
return $this->entityManager->getRepository($this->entityName);
}
}

namespace CustomerBundle\Repository;

use Doctrine\ORM\EntityManagerInterface;

class CustomerRepository extends AbstractRepository
{
public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct($entityManager, Customer::class);
}

public function findAll()
{
return $this->getRepository()->createQueryBuilder('c')
->getQuery()
->getArrayResult();
}

public function findOneById($id)
{
return $this->getRepository()->createQueryBuilder('c')
->where('c.id = :id')
->setParameter('id', $id)
->getQuery()
->getOneOrNullResult();
}
}

CustomerBundle\Repository\CustomerRepository: ~
CustomerBundle\Repository\CustomerRepositoryInterface: '@CustomerBundle\Repository\CustomerRepository'

Repository - V2


namespace CustomerBundle\Repository;

interface CustomerRepositoryInterface
{
public function findAll();
public function findOneById($id);
}

namespace CustomerBundle\Repository;

use Doctrine\ORM\EntityRepository;

class CustomerRepository implements CustomerRepositoryInterface
{
private $entityRepository;

public function __construct(EntityRepository $entityRepository)
{
$this->entityRepository = $entityRepository;
}

public function findAll()
{
return $this->entityRepository->createQueryBuilder('c')
->getQuery()
->getArrayResult();
}

public function findOneById($id)
{
return $this->entityRepository->createQueryBuilder('c')
->where('c.id = :id')
->setParameter('id', $id)
->getQuery()
->getOneOrNullResult();
}
}

services:
customer.doctrine.entity_repository:
class: Doctrine\ORM\EntityRepository
factory: [ "@doctrine.orm.entity_manager", getRepository ]
arguments:
- CustomerBundle\Entity\Customer

customer.repository.customer:
class: CustomerBundle\Repository\CustomerRepository
arguments:
- "@customer.doctrine.entity_repository"