alengo/doctrine-compatibility-bundle
Installation
Add the bundle to your composer.json:
composer require alengo/doctrine-compatibility-bundle
Enable the bundle in config/bundles.php:
return [
// ...
Alengo\DoctrineCompatibilityBundle\AlengoDoctrineCompatibilityBundle::class => ['all' => true],
];
First Use Case: Doctrine ORM 3.x Compatibility If you’re migrating from Doctrine ORM 2.x to 3.x in a Sulu 3 project, this bundle patches common breaking changes. No additional configuration is required—it auto-detects and applies fixes.
Gedmo Extensions Support
If using Gedmo DoctrineExtensions (e.g., Timestampable, Sortable, Translatable), ensure your AppKernel.php or config/bundles.php includes:
Gedmo\DoctrineExtensionsBundle\GedmoDoctrineExtensionsBundle::class => ['all' => true],
The bundle ensures Gedmo’s event listeners and lifecycle callbacks remain compatible with Doctrine 3.x.
Update Dependencies
composer require doctrine/orm:^3.0 doctrine/doctrine-bundle:^2.9
Apply Patches The bundle automatically patches:
EntityManager initialization (e.g., getRepository() behavior).EventManager compatibility (e.g., postLoad/prePersist events).MetadataFactory adjustments for Sulu’s custom mappings.Test Critical Paths Focus on:
findBy(), createQueryBuilder()).@ORM\PrePersist).Webspace, Page).Sulu Admin Integration If using Sulu’s admin interface, verify that:
sulu_core.event.entity.updated still trigger.Media) work with Doctrine 3.x’s event system.Custom Doctrine Events Extend the bundle’s patches by creating a custom event subscriber:
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Events;
class CustomDoctrineSubscriber implements EventSubscriber
{
public function getSubscribedEvents()
{
return [Events::postLoad];
}
public function postLoad(LifecycleEventArgs $args) { /* ... */ }
}
Register it in services.yaml:
services:
App\CustomDoctrineSubscriber:
tags: [doctrine.event_subscriber]
Translatable Entities
Ensure your Translatable entities extend Gedmo\Mapping\Annotation\Translation correctly. Example:
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @Gedmo\TranslationEntity(class="App\Entity\PageTranslation")
*/
class Page { /* ... */ }
Sortable Entities
For Sortable behavior, add the position field and annotation:
/**
* @Gedmo\SortablePosition
* @ORM\Column(type="integer")
*/
private $position;
Event Listener Order
Doctrine 3.x enforces stricter event subscriber priority. If your custom listeners fail, explicitly set priority in getSubscribedEvents():
return [
Events::postLoad => ['method' => 'postLoad', 'priority' => 10], // Higher = earlier
];
Sulu-Specific Metadata
Sulu 3 uses custom Doctrine metadata (e.g., for Media or Page). If you encounter ClassMetadata errors, clear the cache:
php bin/console cache:clear
Gedmo Timestampable Conflicts
If createdAt/updatedAt fields behave unexpectedly, ensure:
Timestampable listener is registered after the bundle’s patches.DateTimeImmutable (Doctrine 3.x default).Enable Doctrine Debugging
Add to config/packages/dev/doctrine.yaml:
doctrine:
orm:
entity_managers:
default:
logging: true
dbal:
logging: true
Check logs in var/log/dev.log for SQL/ORM events.
Common Errors & Fixes
| Error | Solution |
|---|---|
ClassMetadata not found for App\Entity\Page |
Run php bin/console doctrine:schema:update --force. |
Event "postLoad" does not exist |
Ensure the bundle is loaded before your custom subscribers. |
Gedmo\Exception\InvalidArgumentException: No translation entity found |
Verify @Gedmo\TranslationEntity is correctly annotated. |
Custom Patches Override the bundle’s patches by creating a compiler pass:
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class CustomDoctrinePatchPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$definition = $container->findDefinition('doctrine.orm.entity_manager');
$definition->addMethodCall('addEventSubscriber', [new Reference('app.custom_subscriber')]);
}
}
Register the pass in services.yaml:
services:
App\CustomDoctrinePatchPass:
tags: [compiler_pass]
Doctrine 3.x Features Leverage new features like return types in repositories:
public function findOneById(int $id): ?Page
{
return $this->createQueryBuilder('p')
->where('p.id = :id')
->setParameter('id', $id)
->getQuery()
->getOneOrNullResult();
}
Performance Tips
Doctrine\ORM\QueryBuilder for complex queries (Doctrine 3.x optimizes this).EntityManager::flush() to reduce database roundtrips.How can I help you explore Laravel packages today?