Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Doctrine Bundle Laravel Package

doctrine/doctrine-bundle

Symfony bundle integrating Doctrine DBAL and ORM. Provides database abstraction, schema tools, and an object-relational mapper with DQL for powerful queries, plus configuration and tooling that fits the Symfony ecosystem.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require doctrine/doctrine-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
    ];
    
  2. Configuration: Edit config/packages/doctrine.yaml:

    dbal:
        url: '%env(DATABASE_URL)%'
        # or driver-specific config:
        # driver: 'pdo_mysql'
        # server_version: '8.0'
        # charset: 'utf8mb4'
    
    orm:
        auto_generate_proxy_classes: true
        naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
        auto_mapping: true
        mappings:
            App:
                is_bundle: false
                dir: '%kernel.project_dir%/src/Entity'
                prefix: 'App\Entity'
                alias: App
    
  3. First Use Case: Create an entity (src/Entity/User.php):

    namespace App\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    
    #[ORM\Entity]
    class User
    {
        #[ORM\Id]
        #[ORM\GeneratedValue]
        #[ORM\Column]
        private ?int $id = null;
    
        #[ORM\Column(length: 255)]
        private string $name;
    
        // getters/setters...
    }
    

    Run migrations:

    php bin/console doctrine:migrations:diff
    php bin/console doctrine:migrations:migrate
    

Implementation Patterns

Core Workflows

  1. Entity Management:

    • CRUD Operations:
      $user = $entityManager->find(User::class, 1);
      $entityManager->persist($newUser);
      $entityManager->flush();
      
    • Repository Pattern:
      $users = $entityManager->getRepository(User::class)->findBy(['name' => 'John']);
      
  2. Querying:

    • DQL (Doctrine Query Language):
      $query = $entityManager->createQuery('SELECT u FROM App\Entity\User u WHERE u.name = :name')
          ->setParameter('name', 'John');
      
    • QueryBuilder:
      $qb = $entityManager->createQueryBuilder();
      $qb->select('u')
         ->from(User::class, 'u')
         ->where('u.name = :name')
         ->setParameter('name', 'John');
      
  3. Migrations:

    • Generate and execute:
      php bin/console make:migration
      php bin/console doctrine:migrations:migrate
      
    • Rollback:
      php bin/console doctrine:migrations:rollback
      
  4. Event Listeners/Subscribers:

    • Register in config/packages/doctrine.yaml:
      orm:
          entity_listeners:
              App\EventListener\UserListener: ~
      
    • Example listener:
      namespace App\EventListener;
      
      use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener;
      use Doctrine\ORM\Event\LifecycleEventArgs;
      
      #[AsEntityListener]
      class UserListener
      {
          public function prePersist(LifecycleEventArgs $args): void
          {
              $user = $args->getObject();
              $user->setCreatedAt(new \DateTime());
          }
      }
      
  5. Custom DQL Functions:

    • Register in config/packages/doctrine.yaml:
      orm:
          dql:
              string_functions:
                  CONCAT_WS: DoctrineExtensions\Query\Mysql\StringFunctions\ConcatWs
      

Integration Tips

  1. Symfony Forms:

    use Symfony\Bridge\Doctrine\Form\Type\EntityType;
    
    $builder->add('user', EntityType::class, [
        'class' => User::class,
        'choice_label' => 'name',
    ]);
    
  2. API Platform:

    # config/packages/api_platform.yaml
    api_platform:
        formats:
            jsonld:
                mime_types: ['application/ld+json']
        patch_formats:
            json: ['application/merge-patch+json']
        swagger:
            versions: [3]
    
  3. Testing:

    use Doctrine\ORM\Tools\SchemaTool;
    
    public function setUp(): void
    {
        $schemaTool = new SchemaTool($this->entityManager);
        $schemaTool->dropDatabase();
        $schemaTool->createSchema($this->entityManager->getMetadataFactory()->getAllMetadata());
    }
    
  4. Caching:

    orm:
        metadata_cache_driver: apcu
        query_cache_driver: apcu
        result_cache_driver: apcu
    

Gotchas and Tips

Common Pitfalls

  1. Proxy Classes:

    • Issue: Forgetting to clear cache after adding new entities.
    • Fix: Run:
      php bin/console cache:clear
      php bin/console doctrine:cache:clear-metadata
      php bin/console doctrine:cache:clear-query
      php bin/console doctrine:cache:clear-result
      
    • Tip: Use auto_generate_proxy_classes: true in development and set to false in production with manual generation.
  2. Naming Conflicts:

    • Issue: Underscore vs. camelCase in entity properties.
    • Fix: Configure naming strategy:
      orm:
          naming_strategy: doctrine.orm.naming_strategy.underscore
      
  3. Lazy Loading:

    • Issue: N+1 query problem.
    • Fix: Use fetch="EAGER" or DQL joins:
      $query = $entityManager->createQuery('SELECT u, a FROM App\Entity\User u LEFT JOIN u.addresses a');
      
  4. Transactions:

    • Issue: Long-running transactions blocking DB.
    • Fix: Commit early or use read-only transactions:
      $entityManager->beginTransaction();
      try {
          // Operations...
          $entityManager->commit();
      } catch (\Exception $e) {
          $entityManager->rollback();
      }
      
  5. Schema Updates:

    • Issue: Schema updates failing silently.
    • Fix: Use --complete flag:
      php bin/console doctrine:schema:update --complete
      

Debugging Tips

  1. Enable SQL Logging:

    dbal:
        logging: true
        profiling: true
    

    View logs in var/log/dev.log.

  2. Query Profiling:

    $profiler = $entityManager->getConnection()->getConfiguration()->getSQLLogger();
    $profiler->startQueryLogging();
    // ... execute queries ...
    $queries = $profiler->getQueries();
    
  3. Entity Metadata:

    $metadata = $entityManager->getClassMetadata(User::class);
    dump($metadata->getFieldNames());
    
  4. Event Debugging:

    orm:
        eventmanager: doctrine.eventmanager
    

    Then inject EventManager and log events:

    $eventManager->addEventListener([LifecycleEventArgs::class], function ($args) {
        error_log('Event triggered: ' . get_class($args->getObject()));
    });
    

Configuration Quirks

  1. Deprecated Options:

    • Avoid auto_mapping: true (deprecated). Use explicit mappings:
      orm:
          auto_mapping: false
          mappings:
              App:
                  is_bundle: false
                  dir: '%kernel.project_dir%/src/Entity'
                  prefix: 'App\Entity'
                  alias: App
      
  2. Connection Handling:

    • For multiple databases, configure separately:
      dbal:
          connections:
              default:
                  url: '%env(DATABASE_URL)%'
              read_replica:
                  url: '%env(READ_DATABASE_URL)%'
                  wrapper_class: Doctrine\DBAL\Connection
      
  3. Custom Entity Managers:

    • Register in services.yaml:
      services:
          App\Doctrine\CustomEntityManager:
              alias: doctrine.orm.entity_manager
              public: true
      

Extension Points

  1. Custom Types:
    • Create a type and register it:
      namespace App\Doctrine\DBAL\Types;
      
      use Doctrine\DBAL\Platforms\AbstractPlatform;
      use Doctrine\DBAL\Types\Type;
      
      class JsonType extends Type
      {
          public function getSQLDeclaration(array $column, AbstractPlatform $platform)
          {
              return 'JSON';
          }
      
          // ... other methods ...
      }
      
      Register in config/packages/doctrine.yaml:
      dbal:
          types:
              json: App\Doctrine\DBAL\Types\JsonType
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport