Weave 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

ruvents/doctrine-bundle

A Symfony bundle that integrates Doctrine ORM by registering entity managers, database connections, and mapping configuration. It provides default services and config for Doctrine-backed applications, simplifying persistence setup.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install the bundle with composer require ruvents/doctrine-bundle. On Laravel 5.5+ the service provider is auto-discovered; on older versions register Ruvents\DoctrineBundle\DoctrineServiceProvider manually in config/app.php.
  • Publish the config first: php artisan vendor:publish --provider="Ruvents\DoctrineBundle\DoctrineServiceProvider". This gives you the config/doctrine.php-style file where you define connections, the metadata driver (annotation, xml, or yaml), proxy directory, and cache backend.
  • The first place to look after install is the service provider source. Because the bundle is small and archived, the provider is the authoritative map of what gets bound into the container — especially the EntityManager binding and how it reads config keys. Read it before trusting any tutorial you find online.
  • First practical use case: create a single entity in app/Entities, point the metadata driver at that namespace, and confirm the EntityManager resolves and can persist()/flush() it. For example, a User entity with a @ORM\Entity annotation and a matching repository class, then fetch it with $em->getRepository(User::class)->findAll().
  • If you rely on migrations, verify the Artisan commands the bundle registers (doctrine:schema:create, doctrine:schema:update, doctrine:migrations:* depending on what the provider wires up) show up in php artisan list before writing code. If they don't, the config is wrong, not the commands.

Implementation Patterns

  • Inject the EntityManager into services, not controllers. The bundle binds it on the container, so a constructor type-hint is the cleanest integration. Keep controllers thin: one call into a service that owns the unit of work.
  • Repositories as the read surface. Map each entity to a custom repository via repositoryClass and expose named finder methods (findActiveForAccount()). This mirrors the "custom repositories" feature and keeps DQL out of your application layer.
  • Explicit transaction boundaries for writes. Doctrine's unit of work is request-scoped in spirit: persist several entities, flush() once, wrap multi-step operations in $em->transactional(fn () => ...). Avoid calling flush() inside loops — batch and flush per unit of work.
  • Keep Eloquent and Doctrine on separate connections. Reuse the existing database.connections entry by name in the Doctrine config rather than duplicating credentials, but treat the two persistence layers as separate schemas-of-record. Do not write the same table from both.
  • Schema tooling in CI. Use doctrine:schema:validate in CI and generate schema diffs in code review. Because the bundle predates modern migration tooling, most teams drive schema from entity metadata and treat Eloquent migrations as unrelated infrastructure (jobs, cache, etc.).
  • Metadata drivers per project, not per package. Pick one driver (annotations are the documented path) and stick to it. Mixing XML/YAML with annotations works technically but confuses IDE tooling and makes upgrade debugging harder.
  • DQL and QueryBuilder via the manager. Write custom DQL functions and query hints through the manager's configuration rather than subclassing; that's the intended extension point and survives a composer update better than forking.
  • Testing pattern. Build an EntityManager against an in-memory SQLite connection in your base TestCase, create the schema once, and truncate between tests. Mock the manager only for pure unit tests of services; integration tests should exercise real flush/identity-map behavior.

Gotchas and Tips

  • The package is archived and last released in 2018. Pin the exact version ("ruvents/doctrine-bundle": "0.2.2"), commit the lock file, and plan an exit path. The most realistic alternative is wiring Doctrine ORM directly in a small service provider — it's a couple hundred lines and removes a dead dependency from a critical path.
  • PHP and Doctrine version drift is the biggest risk. The 2018-era bundle was built against older doctrine/orm and doctrine/annotations. On PHP 8+, annotations are deprecated and doctrine/annotations reading order/case changed. Expect to need to bump transitive Doctrine packages, and expect the bundle's provider to break when you do. Test the upgrade on a branch.
  • Proxy directory must be writable and outside the web root. If entities silently fail to hydrate or you get "cannot find proxy," check the configured proxy path and its permissions first. Clear it (rm -rf) when entity mappings change in development.
  • Clear Laravel caches after any config or mapping change. php artisan config:clear && php artisan cache:clear — and if you cache the metadata (recommended for production), invalidate it on deploy. Stale metadata caches are the #1 source of "why is my new field ignored" bugs.
  • No Eloquent events, observers, or model factories. Do not expect saving/saved hooks or Model::factory(). Use Doctrine lifecycle callbacks (@PrePersist, @PreUpdate) or EventSubscriber registrations through the config; factories must be hand-rolled.
  • The identity map bites after bulk operations. After $em->createQuery('DELETE ...')->execute() or a DQL update, the in-memory entities are stale. Call $em->clear() (and refresh entities you still need) or you will persist wrong data silently.
  • Migrations table collision. If the bundle's migration tooling uses a migrations table and you also run Eloquent migrations, configure a distinct table name in the Doctrine config. Otherwise one system will see the other's rows as unknown migrations.
  • Debugging queries. There is no Laravel Telescope integration. Register a SQLLogger ($em->getConnection()->getConfiguration()->setSQLLogger(...)) or an EventSubscriber on postFlush/onFlush in local dev. Dump DQL via $query->getSQL() before executing when a QueryException is opaque.
  • Config key drift between bundle versions. Because it's pre-1.0, config keys can move between point releases. When something stops being bound, diff vendor/ruvents/doctrine-bundle/src against the version you upgraded from — that's faster than reading release notes that barely exist.
  • Extension points worth using: custom DQL functions, EventSubscribers, and custom repository classes are all wired through config and are the supported ways to bend behavior. Do not subclass or copy the provider's bootstrapping into your AppServiceProvider; that couples you to internals and makes the eventual migration off the bundle much harder.
  • Budget upgrade time per release cycle. Even on a stable 0.2.2, the surrounding Doctrine ecosystem will move and force you forward. Treat this as a dependency with an owner assigned, not a set-and-forget install.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource