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

brandoriented/doctrine-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle via Composer:

    composer require doctrine/doctrine-bundle
    

    Enable the bundle in config/bundles.php:

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

    doctrine:
        dbal:
            url: '%env(DATABASE_URL)%'
        orm:
            auto_generate_proxy_classes: true
            naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
            auto_mapping: true
            mappings:
                App:
                    is_bundle: false
                    type: annotation
                    dir: '%kernel.project_dir%/src/Entity'
                    prefix: 'App\Entity'
                    alias: App
    
  3. First Use Case Create an entity (e.g., src/Entity/User.php):

    namespace App\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    
    #[ORM\Entity(repositoryClass: UserRepository::class)]
    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:schema:update --force
    

Implementation Patterns

Common Workflows

  1. Repository Pattern Use repositories for complex queries (e.g., src/Repository/UserRepository.php):

    namespace App\Repository;
    
    use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
    use Doctrine\Persistence\ManagerRegistry;
    
    class UserRepository extends ServiceEntityRepository
    {
        public function __construct(ManagerRegistry $registry)
        {
            parent::__construct($registry, User::class);
        }
    
        public function findActiveUsers(): array
        {
            return $this->createQueryBuilder('u')
                ->where('u.isActive = :active')
                ->setParameter('active', true)
                ->getQuery()
                ->getResult();
        }
    }
    
  2. QueryBuilder for Dynamic Queries Build flexible queries in controllers/services:

    $qb = $this->createQueryBuilder('u')
        ->select('u.id', 'u.name')
        ->where('u.createdAt > :date')
        ->setParameter('date', new \DateTime('-1 week'));
    
  3. Lifecycle Callbacks Use @ORM\PrePersist, @ORM\PostUpdate, etc., for entity events:

    #[ORM\PrePersist]
    public function setCreatedAt(): void
    {
        $this->createdAt = new \DateTime();
    }
    
  4. DQL for Complex Joins Leverage Doctrine Query Language for readability:

    $query = $this->createQueryBuilder('u')
        ->select('u, p')
        ->join('u.products', 'p')
        ->where('p.price > :minPrice')
        ->getQuery();
    
  5. Event Subscribers Hook into Doctrine events (e.g., src/EventSubscriber/UserSubscriber.php):

    namespace App\EventSubscriber;
    
    use Doctrine\Common\EventSubscriber;
    use Doctrine\ORM\Event\LifecycleEventArgs;
    
    class UserSubscriber implements EventSubscriber
    {
        public function getSubscribedEvents(): array
        {
            return ['prePersist', 'preUpdate'];
        }
    
        public function prePersist(LifecycleEventArgs $args): void
        {
            $entity = $args->getObject();
            if ($entity instanceof User) {
                $entity->setUpdatedAt(new \DateTime());
            }
        }
    }
    
  6. Native SQL Queries Use EntityManager::createNativeQuery() for raw SQL:

    $results = $entityManager->createNativeQuery('SELECT * FROM users WHERE active = 1')->getResult();
    

Gotchas and Tips

Pitfalls

  1. Proxy Classes

    • Forgetting to clear cache (php bin/console cache:clear) after adding new entities can cause ClassNotFoundException.
    • Fix: Run php bin/console doctrine:cache:clear-metadata or enable auto_generate_proxy_classes: true.
  2. Case Sensitivity

    • Doctrine ORM is case-sensitive by default. Use naming_strategy to handle underscores/camelCase:
      orm:
          naming_strategy: doctrine.orm.naming_strategy.underscore
      
  3. Lazy Loading

    • Eager-loading associations (fetch: EAGER) can cause performance issues. Prefer lazy loading (fetch: LAZY) and fetch only when needed.
    • Debug: Use #[ORM\ManyToOne(fetch: 'EAGER')] sparingly.
  4. Transaction Management

    • Forgetting to commit transactions in services can lead to silent failures.
    • Tip: Use try-catch blocks with rollback():
      $entityManager->beginTransaction();
      try {
          $entityManager->persist($entity);
          $entityManager->flush();
          $entityManager->commit();
      } catch (\Exception $e) {
          $entityManager->rollback();
          throw $e;
      }
      
  5. Circular References

    • Bidirectional associations without proper inversedBy/mappedBy cause infinite loops.
    • Fix: Always define both sides:
      #[ORM\ManyToMany(targetEntity: Product::class, inversedBy: 'users')]
      private Collection $users;
      
  6. Schema Updates

    • Running doctrine:schema:update --force in production can be risky. Use migrations (doctrine:migrations:diff + doctrine:migrations:migrate) instead.

Debugging Tips

  1. Query Logging Enable SQL logging in config/packages/dev/doctrine.yaml:

    dbal:
        logging: true
        profiling: true
    

    View queries in Symfony Profiler or var/log/dev.log.

  2. Entity Manager Debugging Use getMetadataFactory() to inspect entities:

    $metadata = $entityManager->getMetadataFactory()->getMetadataFor(User::class);
    dump($metadata->getAssociationMappings());
    
  3. Common Errors

    • "Class is not mapped": Ensure the entity is annotated/attribute-decorated and auto-mapping is configured.
    • "Invalid column name": Check for typos in @ORM\Column or schema mismatches.

Extension Points

  1. Custom DQL Functions Register custom functions in doctrine.yaml:

    orm:
        dql:
            string_functions:
                CONCAT: Doctrine\ORM\Query\AST\Functions\StringFunction
    
  2. Event Listeners Create listeners for global logic (e.g., logging, auditing):

    namespace App\EventListener;
    
    use Doctrine\Common\EventSubscriber;
    use Doctrine\ORM\Event\OnFlushEventArgs;
    
    class AuditListener implements EventSubscriber
    {
        public function getSubscribedEvents(): array
        {
            return ['onFlush'];
        }
    
        public function onFlush(OnFlushEventArgs $args): void
        {
            $entityManager = $args->getEntityManager();
            $uow = $entityManager->getUnitOfWork();
            // Custom logic...
        }
    }
    
  3. Custom Repository Factories Override repository creation for custom logic:

    orm:
        repository_factory: App\Doctrine\CustomRepositoryFactory
    
  4. Database Platform-Specific Features Use getDatabasePlatform() to write platform-aware queries:

    $platform = $entityManager->getConnection()->getDatabasePlatform();
    if ($platform->supportsLimitOffset()) {
        $qb->setMaxResults(10)->setFirstResult(0);
    }
    
  5. Hybrid ODMMappings Combine ORM and DBAL for mixed persistence strategies:

    orm:
        mappings:
            App:
                type: xml
                dir: '%kernel.project_dir%/config/doctrine'
                prefix: 'App\Entity'
    
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.
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor
spatie/laravel-javascript-views