symfony/doctrine-bridge
Symfony Doctrine Bridge integrates Doctrine ORM and related libraries with Symfony components, providing seamless wiring for services, repositories, persistence, and tooling. Ideal for projects using Doctrine alongside Symfony’s DI container, validator, and other features.
Installation:
composer require symfony/doctrine-bridge
This package is typically included as a dependency of symfony/framework-bundle, so explicit installation is rare unless extending functionality.
First Use Case:
@Assert\Email, @Assert\Length) and leverage the bridge to auto-validate during form submission or API requests.
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Entity]
class User
{
#[ORM\Id, ORM\GeneratedValue]
#[Assert\NotBlank]
private ?int $id = null;
#[Assert\Email]
private string $email;
}
Symfony\Bridge\Doctrine\Form\Type\EntityType to bind Doctrine entities to Symfony forms:
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
$builder->add('user', EntityType::class, [
'class' => User::class,
'choice_label' => 'email',
]);
Where to Look First:
Symfony\Bridge\Doctrine for advanced use cases (e.g., custom types, event listeners).config/packages/doctrine.yaml for Doctrine configuration and services.yaml for custom Doctrine services.Entity-Driven Development:
@ORM\*) for database mapping.@Assert\*) for business rules.@Groups) for API payloads.#[ORM\Entity(repositoryClass: UserRepository::class)]
#[UniqueEntity('email')]
#[ApiResource(
collectionOperations: ['get', 'post'],
itemOperations: ['get', 'put', 'delete']
)]
class User { ... }
Form-Entity Binding:
EntityType or Form\Type\FormType with data_class.AbstractType.EntityType for entity fields or FormType for custom logic.$form = $this->createFormBuilder($user)
->add('email', EmailType::class)
->add('save', SubmitType::class)
->getForm();
Security Integration:
UserProvider for Symfony’s security system.UserInterface and PasswordAuthenticatedUserInterface in your entity.security.yaml to use doctrine as the user provider.PersistentToken for "remember me" functionality.# config/packages/security.yaml
security:
providers:
app_user_provider:
entity:
class: App\Entity\User
property: email
Event Listeners and Subscribers:
prePersist, postUpdate) via Symfony’s event dispatcher.use Doctrine\ORM\Event\LifecycleEventArgs;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
#[AsEventListener(event: 'prePersist', method: 'onPrePersist')]
public function onPrePersist(User $user, LifecycleEventArgs $args): void
{
$user->setCreatedAt(new \DateTime());
}
Custom Doctrine Types:
DayPointType, TimePointType).AbstractPlatformSpecificType.doctrine.yaml:doctrine:
dbal:
types:
day_point: App\Doctrine\DBAL\Types\DayPointType
#[ORM\Column(type: 'day_point')]
private DayPoint $startDate;
API Platform Integration:
api-platform/core with Doctrine for auto-generated REST/GraphQL APIs.#[ApiResource(
normalizationContext: ['groups' => ['user:read']],
denormalizationContext: ['groups' => ['user:write']]
)]
class User { ... }
CRUD Operations:
EntityRepository or Doctrine\ORM\EntityManager:
$user = $entityManager->getRepository(User::class)->find($id);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->persist($user);
$entityManager->flush();
}
EntityManager::remove():
$entityManager->remove($user);
$entityManager->flush();
Validation Workflow:
$form->submit($data);
if ($form->isSubmitted() && $form->isValid()) {
// Proceed with persistence
}
$validator = $this->container->get('validator');
$errors = $validator->validate($entity);
if (count($errors) > 0) {
// Handle errors
}
Database Migrations:
doctrine:migrations:diff and doctrine:migrations:migrate:
php bin/console make:migration
php bin/console doctrine:migrations:migrate
Symfony Flex Recipes:
symfony/recipe to auto-configure Doctrine with Symfony’s ecosystem (e.g., api-platform, maker-bundle).composer require api
Dependency Injection:
autoconfigure: true in services.yaml:
services:
App\EventSubscriber\UserSubscriber:
tags: ['doctrine.event_subscriber']
Testing:
Doctrine\ORM\EntityManagerInterface in tests with in-memory databases:
$entityManager = $this->getEntityManager();
$entityManager->persist($user);
$entityManager->flush();
EntityManager for unit tests:
$entityManager = $this->createMock(EntityManagerInterface::class);
Performance:
# config/packages/doctrine.yaml
doctrine:
orm:
second_level_cache:
enabled: true
region_directory: '%kernel.cache_dir%/doctrine'
Deprecations in Symfony 8+:
AbstractDoctrineExtension is removed in Symfony 8.0. Replace with custom form types or extensions.PersistentToken::getClass() and RememberMeDetails::getUserFqcn() are deprecated. Use getUserIdentifier() instead.Schema Subscriber Check:
_schema_subscriber_check table may conflict with Oracle. Rename it via schema_subscriber_check_ (fixed in v8.0.7+).UniqueEntity Validator:
UniqueEntity validator may fail with Stringable identifiers (e.g., Uuid).fields option uses scalar types or implement __toString() in your entity.Same-Database Check:
SameDatabaseChecker may throw exceptions if the database driver is misconfigured. Catch all driver exceptions (fixed in v8.0.9).Custom Types and UID:
Uid may fail if notHow can I help you explore Laravel packages today?