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 Cache Invalidation Bundle Laravel Package

c2is/doctrine-cache-invalidation-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle to your composer.json:

    composer require c2is/doctrine-cache-invalidation-bundle
    

    Register the bundle in config/bundles.php:

    return [
        // ...
        C2is\DoctrineCacheInvalidationBundle\C2isDoctrineCacheInvalidationBundle::class => ['all' => true],
    ];
    
  2. First Use Case Invalidate Doctrine's query cache for a specific entity or query:

    use C2is\DoctrineCacheInvalidationBundle\CacheInvalidator;
    
    // In your service/controller
    $cacheInvalidator = $this->container->get('c2is.doctrine_cache_invalidation.cache_invalidator');
    $cacheInvalidator->invalidateEntityCache('App\Entity\Product', 123); // Invalidate cache for Product with ID 123
    
  3. Where to Look First

    • Documentation: Resources/doc/
    • Service Configuration: Check config/packages/c2is_doctrine_cache_invalidation.yaml (if auto-generated).
    • Event Listeners: The bundle provides listeners for onFlush and postFlush events by default.

Implementation Patterns

Core Workflows

  1. Manual Cache Invalidation Trigger cache invalidation programmatically in services/controllers:

    // Invalidate all cached results for an entity class
    $cacheInvalidator->invalidateEntityCache('App\Entity\User');
    
    // Invalidate a specific entity instance
    $cacheInvalidator->invalidateEntityCache('App\Entity\User', $userId);
    
  2. Automatic Invalidation via Events The bundle hooks into Doctrine lifecycle events (onFlush, postFlush). Extend or override the default behavior:

    # config/packages/c2is_doctrine_cache_invalidation.yaml
    c2is_doctrine_cache_invalidation:
        listeners:
            on_flush: true    # Default: true
            post_flush: true  # Default: true
    
  3. Integration with Custom Logic Use the CacheInvalidator service in custom event subscribers or commands:

    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    
    class ClearProductCacheCommand extends Command
    {
        protected function execute(InputInterface $input, OutputInterface $output)
        {
            $cacheInvalidator = $this->getContainer()->get('c2is.doctrine_cache_invalidation.cache_invalidator');
            $cacheInvalidator->invalidateEntityCache('App\Entity\Product');
            $output->writeln('Product cache invalidated!');
        }
    }
    
  4. Partial Cache Invalidation Invalidate only specific queries or DQL fragments (advanced):

    $cacheInvalidator->invalidateQueryCache('SELECT p FROM App\Entity\Product p WHERE p.category = :category');
    

Best Practices

  • Use in postUpdate/postRemove: Invalidate cache after entity updates/deletions.
  • Avoid Overuse: Manual invalidation should target specific entities/queries, not entire caches.
  • Test Cache Behavior: Verify cache invalidation works as expected in tests:
    $this->getContainer()->get('c2is.doctrine_cache_invalidation.cache_invalidator')
        ->invalidateEntityCache('App\Entity\TestEntity');
    

Gotchas and Tips

Pitfalls

  1. Event Timing Issues

    • If onFlush invalidation fails, switch to postFlush or vice versa.
    • Debug: Check Doctrine events in debug:event-dispatcher:
      php bin/console debug:event-dispatcher
      
  2. Cache Driver Mismatch

    • The bundle assumes Doctrine's default cache driver (APCu, Redis, etc.). If using a custom driver, ensure it supports invalidation:
      // Example: Force a specific cache pool
      $cacheInvalidator->setCachePool($entityManager->getConfiguration()->getQueryCacheImpl());
      
  3. Performance Overhead

    • Frequent invalidations can degrade performance. Use sparingly for high-traffic entities.
    • Tip: Batch invalidations for bulk operations.
  4. Entity Metadata Caching

    • Invalidate metadata cache separately if needed:
      $entityManager->getMetadataFactory()->getMetadataFor('App\Entity\User')->setCacheDriver(null);
      

Debugging Tips

  • Log Invalidation Events Enable debug logging in config/packages/dev/monolog.yaml:

    handlers:
        doctrine_cache:
            type: stream
            path: "%kernel.logs_dir%/doctrine_cache_invalidation.log"
            level: debug
            channels: ["doctrine"]
    
  • Verify Cache State Use Doctrine's built-in cache tools:

    php bin/console doctrine:query:sql "SELECT * FROM product WHERE category = ?" --em=default
    

    Check for /* HIT */ or /* MISS */ in logs.

Extension Points

  1. Custom Invalidators Create a decorator for CacheInvalidator:

    use C2is\DoctrineCacheInvalidationBundle\CacheInvalidatorInterface;
    
    class CustomCacheInvalidator implements CacheInvalidatorInterface
    {
        private $decorated;
    
        public function __construct(CacheInvalidatorInterface $decorated)
        {
            $this->decorated = $decorated;
        }
    
        public function invalidateEntityCache($entityName, $entityId = null)
        {
            // Custom logic (e.g., log, validate)
            $this->decorated->invalidateEntityCache($entityName, $entityId);
        }
    }
    

    Register as a service:

    services:
        c2is.doctrine_cache_invalidation.cache_invalidator:
            decorates: 'c2is.doctrine_cache_invalidation.cache_invalidator'
            arguments: ['@c2is.doctrine_cache_invalidation.cache_invalidator.inner']
    
  2. Override Default Listeners Disable built-in listeners and implement your own:

    c2is_doctrine_cache_invalidation:
        listeners:
            on_flush: false
            post_flush: false
    

    Create a custom subscriber:

    use Doctrine\Common\EventSubscriber;
    use Doctrine\ORM\Event\OnFlushEventArgs;
    
    class CustomCacheSubscriber implements EventSubscriber
    {
        public function getSubscribedEvents()
        {
            return ['onFlush'];
        }
    
        public function onFlush(OnFlushEventArgs $args)
        {
            // Custom invalidation logic
        }
    }
    
  3. Multi-EntityManager Support If using multiple EntityManagers, bind the invalidator to a specific one:

    $cacheInvalidator = $this->container->get('c2is.doctrine_cache_invalidation.cache_invalidator');
    $cacheInvalidator->setEntityManager($secondEntityManager);
    
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware