From ed9ba16ff4c397d0d0401a6659a3128da7d743d4 Mon Sep 17 00:00:00 2001 From: Yevhen Sidelnyk Date: Tue, 5 Aug 2025 18:13:36 +0300 Subject: [PATCH] Feature: add support for `ClassLocator` In the scope of https://github.com/doctrine/persistence/pull/433 (available from `doctrine/persistence` >= 4.1) there was added `ColocatedMappingDriver::$classLocator` (`ClassLocator`) property, which allows passing any instance of `ClassLocator` for the mapping driver to use. This commit integrates those changes into `AttributeDriver`. Since `doctrine/orm` maintains the support for `doctrine/persistence` of older versions, tests ensure that `ClassLocator` actually exists. The old paths' behaviour can be adapted into the new by passing `FileClassLocator` into `AttributeDriver` (see `FileClassLocator::createFromDirectories($directoryPaths)`). --- docs/en/reference/advanced-configuration.rst | 56 +++++++++++++++++-- src/Mapping/Driver/AttributeDriver.php | 14 +++-- src/ORMSetup.php | 9 +-- tests/Performance/EntityManagerFactory.php | 17 +++--- tests/Tests/Mocks/AttributeDriverFactory.php | 34 +++++++++++ tests/Tests/Mocks/EntityManagerMock.php | 3 +- tests/Tests/ORM/Functional/EnumTest.php | 7 ++- .../Functional/Locking/LockAgentWorker.php | 5 +- .../ORM/Functional/ReadonlyPropertiesTest.php | 11 ++-- .../Tests/ORM/Mapping/AttributeDriverTest.php | 19 ++++++- .../ORM/Persisters/BinaryIdPersisterTest.php | 20 ++++++- .../Command/SchemaTool/CommandTestCase.php | 7 +-- tests/Tests/OrmFunctionalTestCase.php | 15 +++-- tests/Tests/OrmTestCase.php | 9 ++- 14 files changed, 169 insertions(+), 57 deletions(-) create mode 100644 tests/Tests/Mocks/AttributeDriverFactory.php diff --git a/docs/en/reference/advanced-configuration.rst b/docs/en/reference/advanced-configuration.rst index d320f436680..02ac470dd3a 100644 --- a/docs/en/reference/advanced-configuration.rst +++ b/docs/en/reference/advanced-configuration.rst @@ -29,7 +29,7 @@ steps of configuration. $config = new Configuration; $config->setMetadataCache($metadataCache); - $driverImpl = new AttributeDriver(['/path/to/lib/MyProject/Entities'], true); + $driverImpl = new AttributeDriver(['/path/to/lib/MyProject/Entities']); $config->setMetadataDriverImpl($driverImpl); $config->setQueryCache($queryCache); @@ -154,15 +154,59 @@ The attribute driver can be injected in the ``Doctrine\ORM\Configuration``: setMetadataDriverImpl($driverImpl); The path information to the entities is required for the attribute driver, because otherwise mass-operations on all entities through -the console could not work correctly. All of metadata drivers -accept either a single directory as a string or an array of -directories. With this feature a single driver can support multiple -directories of Entities. +the console could not work correctly. Metadata drivers can accept either +a single directory as a string or an array of directories. + +AttributeDriver also accepts ``Doctrine\Persistence\Mapping\Driver\ClassLocator``, +allowing one to customize file discovery logic. You may choose to use Symfony Finder, or +utilize directory scan with ``FileClassLocator::createFromDirectories()``: + +.. code-block:: php + + setMetadataDriverImpl($driverImpl); + +With this feature, you're empowered to provide a fine-grained iterator of only necessary +files to the Driver. For example, if you are using Vertical Slice architecture, you can +exclude ``*Test.php``, ``*Controller.php``, ``*Service.php``, etc.: + +.. code-block:: php + + files()->in($paths) + ->name('*.php') + ->notName(['*Test.php', '*Controller.php', '*Service.php']); + + $classLocator = new FileClassLocator($finder); + +If you know the list of class names you want to track, use +``Doctrine\Persistence\Mapping\Driver\ClassNames``: + +.. code-block:: php + + setMetadataDriverImpl($driverImpl); Metadata Cache (**RECOMMENDED**) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/Mapping/Driver/AttributeDriver.php b/src/Mapping/Driver/AttributeDriver.php index 4445ea69437..e66a837e841 100644 --- a/src/Mapping/Driver/AttributeDriver.php +++ b/src/Mapping/Driver/AttributeDriver.php @@ -10,6 +10,7 @@ use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\MappingException; use Doctrine\Persistence\Mapping\ClassMetadata as PersistenceClassMetadata; +use Doctrine\Persistence\Mapping\Driver\ClassLocator; use Doctrine\Persistence\Mapping\Driver\ColocatedMappingDriver; use Doctrine\Persistence\Mapping\Driver\MappingDriver; use InvalidArgumentException; @@ -35,10 +36,10 @@ class AttributeDriver implements MappingDriver private readonly AttributeReader $reader; /** - * @param array $paths - * @param true $reportFieldsWhereDeclared no-op, to be removed in 4.0 + * @param string[]|ClassLocator $paths a ClassLocator, or an array of directories. + * @param true $reportFieldsWhereDeclared no-op, to be removed in 4.0 */ - public function __construct(array $paths, bool $reportFieldsWhereDeclared = true) + public function __construct(array|ClassLocator $paths, bool $reportFieldsWhereDeclared = true) { if (! $reportFieldsWhereDeclared) { throw new InvalidArgumentException(sprintf( @@ -48,7 +49,12 @@ public function __construct(array $paths, bool $reportFieldsWhereDeclared = true } $this->reader = new AttributeReader(); - $this->addPaths($paths); + + if ($paths instanceof ClassLocator) { + $this->classLocator = $paths; + } else { + $this->addPaths($paths); + } } public function isTransient(string $className): bool diff --git a/src/ORMSetup.php b/src/ORMSetup.php index 458844bb232..df000a838ba 100644 --- a/src/ORMSetup.php +++ b/src/ORMSetup.php @@ -7,6 +7,7 @@ use Doctrine\Deprecations\Deprecation; use Doctrine\ORM\Mapping\Driver\AttributeDriver; use Doctrine\ORM\Mapping\Driver\XmlDriver; +use Doctrine\Persistence\Mapping\Driver\ClassLocator; use Psr\Cache\CacheItemPoolInterface; use Redis; use RuntimeException; @@ -28,10 +29,10 @@ final class ORMSetup /** * Creates a configuration with an attribute metadata driver. * - * @param string[] $paths + * @param string[]|ClassLocator $paths */ public static function createAttributeMetadataConfiguration( - array $paths, + array|ClassLocator $paths, bool $isDevMode = false, string|null $proxyDir = null, CacheItemPoolInterface|null $cache = null, @@ -55,10 +56,10 @@ public static function createAttributeMetadataConfiguration( /** * Creates a configuration with an attribute metadata driver. * - * @param string[] $paths + * @param string[]|ClassLocator $paths */ public static function createAttributeMetadataConfig( - array $paths, + array|ClassLocator $paths, bool $isDevMode = false, string|null $cacheNamespaceSeed = null, CacheItemPoolInterface|null $cache = null, diff --git a/tests/Performance/EntityManagerFactory.php b/tests/Performance/EntityManagerFactory.php index 45b82405aca..3a8c306c1d2 100644 --- a/tests/Performance/EntityManagerFactory.php +++ b/tests/Performance/EntityManagerFactory.php @@ -13,14 +13,13 @@ use Doctrine\ORM\Configuration; use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\Mapping\Driver\AttributeDriver; use Doctrine\ORM\Proxy\ProxyFactory; use Doctrine\ORM\Tools\SchemaTool; use Doctrine\Tests\Mocks\ArrayResultFactory; +use Doctrine\Tests\Mocks\AttributeDriverFactory; use Doctrine\Tests\TestUtil; use function array_map; -use function realpath; final class EntityManagerFactory { @@ -30,9 +29,9 @@ public static function getEntityManager(array $schemaClassNames): EntityManagerI TestUtil::configureProxies($config); $config->setAutoGenerateProxyClasses(ProxyFactory::AUTOGENERATE_EVAL); - $config->setMetadataDriverImpl(new AttributeDriver([ - realpath(__DIR__ . '/Models/Cache'), - realpath(__DIR__ . '/Models/GeoNames'), + $config->setMetadataDriverImpl(AttributeDriverFactory::createAttributeDriver([ + __DIR__ . '/../Tests/Models/Cache', + __DIR__ . '/../Tests/Models/GeoNames', ])); $entityManager = new EntityManager( @@ -55,10 +54,10 @@ public static function makeEntityManagerWithNoResultsConnection(): EntityManager TestUtil::configureProxies($config); $config->setAutoGenerateProxyClasses(ProxyFactory::AUTOGENERATE_EVAL); - $config->setMetadataDriverImpl(new AttributeDriver([ - realpath(__DIR__ . '/Models/Cache'), - realpath(__DIR__ . '/Models/Generic'), - realpath(__DIR__ . '/Models/GeoNames'), + $config->setMetadataDriverImpl(AttributeDriverFactory::createAttributeDriver([ + __DIR__ . '/../Tests/Models/Cache', + __DIR__ . '/../Tests/Models/Generic', + __DIR__ . '/../Tests/Models/GeoNames', ])); // A connection that doesn't really do anything diff --git a/tests/Tests/Mocks/AttributeDriverFactory.php b/tests/Tests/Mocks/AttributeDriverFactory.php new file mode 100644 index 00000000000..7d01d253015 --- /dev/null +++ b/tests/Tests/Mocks/AttributeDriverFactory.php @@ -0,0 +1,34 @@ + $paths */ + public static function createAttributeDriver(array $paths = []): AttributeDriver + { + if (! self::isClassLocatorSupported()) { + // Persistence < 4.1 + return new AttributeDriver($paths); + } + + // Persistence >= 4.1 + $classLocator = FileClassLocator::createFromDirectories($paths); + + return new AttributeDriver($classLocator); + } + + /** Supported since doctrine/persistence >= 4.1 */ + public static function isClassLocatorSupported(): bool + { + return interface_exists(ClassLocator::class); + } +} diff --git a/tests/Tests/Mocks/EntityManagerMock.php b/tests/Tests/Mocks/EntityManagerMock.php index a594045b3f1..b7f5771c0f6 100644 --- a/tests/Tests/Mocks/EntityManagerMock.php +++ b/tests/Tests/Mocks/EntityManagerMock.php @@ -8,7 +8,6 @@ use Doctrine\DBAL\Connection; use Doctrine\ORM\Configuration; use Doctrine\ORM\EntityManager; -use Doctrine\ORM\Mapping\Driver\AttributeDriver; use Doctrine\ORM\Proxy\ProxyFactory; use Doctrine\ORM\UnitOfWork; use Doctrine\Tests\TestUtil; @@ -26,7 +25,7 @@ public function __construct(Connection $conn, Configuration|null $config = null, if ($config === null) { $config = new Configuration(); TestUtil::configureProxies($config); - $config->setMetadataDriverImpl(new AttributeDriver([])); + $config->setMetadataDriverImpl(AttributeDriverFactory::createAttributeDriver()); } parent::__construct($conn, $config, $eventManager); diff --git a/tests/Tests/ORM/Functional/EnumTest.php b/tests/Tests/ORM/Functional/EnumTest.php index f4384d3788b..ad97693aced 100644 --- a/tests/Tests/ORM/Functional/EnumTest.php +++ b/tests/Tests/ORM/Functional/EnumTest.php @@ -7,10 +7,10 @@ use Doctrine\DBAL\Types\EnumType; use Doctrine\ORM\AbstractQuery; use Doctrine\ORM\Mapping\Column; -use Doctrine\ORM\Mapping\Driver\AttributeDriver; use Doctrine\ORM\Mapping\MappingException; use Doctrine\ORM\Query\Expr\Func; use Doctrine\ORM\Tools\SchemaTool; +use Doctrine\Tests\Mocks\AttributeDriverFactory; use Doctrine\Tests\Models\DataTransferObjects\DtoWithArrayOfEnums; use Doctrine\Tests\Models\DataTransferObjects\DtoWithEnum; use Doctrine\Tests\Models\Enums\Card; @@ -28,7 +28,6 @@ use PHPUnit\Framework\Attributes\DataProvider; use function class_exists; -use function dirname; use function sprintf; use function uniqid; @@ -38,7 +37,9 @@ public function setUp(): void { parent::setUp(); - $this->_em = $this->getEntityManager(null, new AttributeDriver([dirname(__DIR__, 2) . '/Models/Enums'], true)); + $mappingDriver = AttributeDriverFactory::createAttributeDriver([__DIR__ . '/../../Models/Enums']); + + $this->_em = $this->getEntityManager(null, $mappingDriver); $this->_schemaTool = new SchemaTool($this->_em); if ($this->isSecondLevelCacheEnabled) { diff --git a/tests/Tests/ORM/Functional/Locking/LockAgentWorker.php b/tests/Tests/ORM/Functional/Locking/LockAgentWorker.php index bd26efd07b0..542ed4b5435 100644 --- a/tests/Tests/ORM/Functional/Locking/LockAgentWorker.php +++ b/tests/Tests/ORM/Functional/Locking/LockAgentWorker.php @@ -9,6 +9,7 @@ use Doctrine\ORM\Configuration; use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\Tests\Mocks\AttributeDriverFactory; use Doctrine\Tests\ORM\Functional\Locking\Doctrine\ORM\Query; use Doctrine\Tests\TestUtil; use GearmanWorker; @@ -116,8 +117,8 @@ protected function createEntityManager(Connection $conn): EntityManagerInterface TestUtil::configureProxies($config); $config->setAutoGenerateProxyClasses(true); - $annotDriver = new AttributeDriver([__DIR__ . '/../../../Models/']); - $config->setMetadataDriverImpl($annotDriver); + $attributeDriver = AttributeDriverFactory::createAttributeDriver([__DIR__ . '/../../../Models']); + $config->setMetadataDriverImpl($attributeDriver); $config->setMetadataCache(new ArrayAdapter()); $config->setQueryCache(new ArrayAdapter()); diff --git a/tests/Tests/ORM/Functional/ReadonlyPropertiesTest.php b/tests/Tests/ORM/Functional/ReadonlyPropertiesTest.php index 67fa9ac1c10..99ff7fda37b 100644 --- a/tests/Tests/ORM/Functional/ReadonlyPropertiesTest.php +++ b/tests/Tests/ORM/Functional/ReadonlyPropertiesTest.php @@ -4,16 +4,14 @@ namespace Doctrine\Tests\ORM\Functional; -use Doctrine\ORM\Mapping\Driver\AttributeDriver; use Doctrine\ORM\Tools\SchemaTool; +use Doctrine\Tests\Mocks\AttributeDriverFactory; use Doctrine\Tests\Models\ReadonlyProperties\Author; use Doctrine\Tests\Models\ReadonlyProperties\Book; use Doctrine\Tests\Models\ReadonlyProperties\SimpleBook; use Doctrine\Tests\OrmFunctionalTestCase; use Doctrine\Tests\TestUtil; -use function dirname; - class ReadonlyPropertiesTest extends OrmFunctionalTestCase { protected function setUp(): void @@ -22,10 +20,9 @@ protected function setUp(): void static::$sharedConn = TestUtil::getConnection(); } - $this->_em = $this->getEntityManager(null, new AttributeDriver( - [dirname(__DIR__, 2) . '/Models/ReadonlyProperties'], - true, - )); + $attributeDriver = AttributeDriverFactory::createAttributeDriver([__DIR__ . '/../../Models/ReadonlyProperties']); + + $this->_em = $this->getEntityManager(null, $attributeDriver); $this->_schemaTool = new SchemaTool($this->_em); parent::setUp(); diff --git a/tests/Tests/ORM/Mapping/AttributeDriverTest.php b/tests/Tests/ORM/Mapping/AttributeDriverTest.php index 58e9de38f67..f50d723008b 100644 --- a/tests/Tests/ORM/Mapping/AttributeDriverTest.php +++ b/tests/Tests/ORM/Mapping/AttributeDriverTest.php @@ -10,7 +10,10 @@ use Doctrine\ORM\Mapping\Driver\AttributeDriver; use Doctrine\ORM\Mapping\JoinColumnMapping; use Doctrine\ORM\Mapping\MappingAttribute; +use Doctrine\Persistence\Mapping\Driver\ClassNames; use Doctrine\Persistence\Mapping\Driver\MappingDriver; +use Doctrine\Tests\Mocks\AttributeDriverFactory; +use Doctrine\Tests\Models\Cache\City; use Doctrine\Tests\ORM\Mapping\Fixtures\AttributeEntityWithNestedJoinColumns; use InvalidArgumentException; use stdClass; @@ -19,9 +22,21 @@ class AttributeDriverTest extends MappingDriverTestCase { protected function loadDriver(): MappingDriver { - $paths = []; + return AttributeDriverFactory::createAttributeDriver(); + } + + public function testDriverCanAcceptClassLocator(): void + { + if (! AttributeDriverFactory::isClassLocatorSupported()) { + self::markTestSkipped('This test is only relevant for versions of doctrine/persistence >= 4.1'); + } + + $classLocator = new ClassNames([City::class]); + + $driver = new AttributeDriver($classLocator); - return new AttributeDriver($paths, true); + self::assertSame([], $driver->getPaths(), 'Directory paths must be empty, since file paths are used'); + self::assertSame([City::class], $driver->getAllClassNames()); } public function testOriginallyNestedAttributesDeclaredWithoutOriginalParent(): void diff --git a/tests/Tests/ORM/Persisters/BinaryIdPersisterTest.php b/tests/Tests/ORM/Persisters/BinaryIdPersisterTest.php index f1ab47277b7..1057a2832d8 100644 --- a/tests/Tests/ORM/Persisters/BinaryIdPersisterTest.php +++ b/tests/Tests/ORM/Persisters/BinaryIdPersisterTest.php @@ -11,6 +11,9 @@ use Doctrine\ORM\ORMSetup; use Doctrine\ORM\Tools\SchemaTool; use Doctrine\ORM\Tools\SchemaValidator; +use Doctrine\Persistence\Mapping\Driver\ClassLocator; +use Doctrine\Persistence\Mapping\Driver\FileClassLocator; +use Doctrine\Tests\Mocks\AttributeDriverFactory; use Doctrine\Tests\Mocks\EntityManagerMock; use Doctrine\Tests\Models\BinaryPrimaryKey\BinaryIdType; use Doctrine\Tests\Models\BinaryPrimaryKey\Category; @@ -65,7 +68,10 @@ private function createEntityManager(): EntityManager return $this->entityManager; } - $config = ORMSetup::createAttributeMetadataConfiguration([__DIR__ . '/../../Models/BinaryPrimaryKey'], isDevMode: true); + $config = ORMSetup::createAttributeMetadataConfiguration( + $this->getClassLocator(), + isDevMode: true, + ); $config->enableNativeLazyObjects(PHP_VERSION_ID >= 80400); if (! DbalType::hasType(BinaryIdType::NAME)) { @@ -85,4 +91,16 @@ private function createEntityManager(): EntityManager return $entityManager; } + + /** @return list|ClassLocator */ + private function getClassLocator(): array|ClassLocator + { + $paths = [__DIR__ . '/../../Models/BinaryPrimaryKey']; + + if (! AttributeDriverFactory::isClassLocatorSupported()) { + return $paths; + } + + return FileClassLocator::createFromDirectories($paths); + } } diff --git a/tests/Tests/ORM/Tools/Console/Command/SchemaTool/CommandTestCase.php b/tests/Tests/ORM/Tools/Console/Command/SchemaTool/CommandTestCase.php index 82279e337b0..9a0159b5a56 100644 --- a/tests/Tests/ORM/Tools/Console/Command/SchemaTool/CommandTestCase.php +++ b/tests/Tests/ORM/Tools/Console/Command/SchemaTool/CommandTestCase.php @@ -5,9 +5,9 @@ namespace Doctrine\Tests\ORM\Tools\Console\Command\SchemaTool; use Doctrine\DBAL\Platforms\SQLitePlatform; -use Doctrine\ORM\Mapping\Driver\AttributeDriver; use Doctrine\ORM\Tools\Console\Command\SchemaTool\AbstractCommand; use Doctrine\ORM\Tools\Console\EntityManagerProvider\SingleManagerProvider; +use Doctrine\Tests\Mocks\AttributeDriverFactory; use Doctrine\Tests\OrmFunctionalTestCase; use Symfony\Component\Console\Tester\CommandTester; @@ -16,9 +16,8 @@ abstract class CommandTestCase extends OrmFunctionalTestCase /** @param class-string $commandClass */ protected function getCommandTester(string $commandClass, string|null $commandName = null): CommandTester { - $entityManager = $this->getEntityManager(null, new AttributeDriver([ - __DIR__ . '/Models', - ])); + $attributeDriver = AttributeDriverFactory::createAttributeDriver([__DIR__ . '/Models']); + $entityManager = $this->getEntityManager(null, $attributeDriver); if (! $entityManager->getConnection()->getDatabasePlatform() instanceof SQLitePlatform) { self::markTestSkipped('We are testing the symfony/console integration'); diff --git a/tests/Tests/OrmFunctionalTestCase.php b/tests/Tests/OrmFunctionalTestCase.php index 67a42d30909..ecf6102695f 100644 --- a/tests/Tests/OrmFunctionalTestCase.php +++ b/tests/Tests/OrmFunctionalTestCase.php @@ -22,7 +22,6 @@ use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Exception\ORMException; use Doctrine\ORM\Mapping\ClassMetadata; -use Doctrine\ORM\Mapping\Driver\AttributeDriver; use Doctrine\ORM\Tools\DebugUnitOfWorkListener; use Doctrine\ORM\Tools\SchemaTool; use Doctrine\ORM\Tools\ToolsException; @@ -31,6 +30,7 @@ use Doctrine\Tests\DbalExtensions\QueryLog; use Doctrine\Tests\DbalTypes\Rot13Type; use Doctrine\Tests\EventListener\CacheMetadataListener; +use Doctrine\Tests\Mocks\AttributeDriverFactory; use Doctrine\Tests\Models\Cache\Action; use Doctrine\Tests\Models\Cache\Address; use Doctrine\Tests\Models\Cache\Attraction; @@ -187,7 +187,6 @@ use function implode; use function is_object; use function method_exists; -use function realpath; use function sprintf; use function str_contains; use function strtolower; @@ -952,12 +951,12 @@ protected function getEntityManager( $config->enableNativeLazyObjects(true); } - $config->setMetadataDriverImpl( - $mappingDriver ?? new AttributeDriver([ - realpath(__DIR__ . '/Models/Cache'), - realpath(__DIR__ . '/Models/GeoNames'), - ], true), - ); + $mappingDriver ??= AttributeDriverFactory::createAttributeDriver([ + __DIR__ . '/Models/Cache', + __DIR__ . '/Models/GeoNames', + ]); + + $config->setMetadataDriverImpl($mappingDriver); $conn = $connection ?: static::$sharedConn; assert($conn !== null); diff --git a/tests/Tests/OrmTestCase.php b/tests/Tests/OrmTestCase.php index e5e4ba0bca4..dba73f5be97 100644 --- a/tests/Tests/OrmTestCase.php +++ b/tests/Tests/OrmTestCase.php @@ -15,6 +15,7 @@ use Doctrine\ORM\Cache\Logging\StatisticsCacheLogger; use Doctrine\ORM\Configuration; use Doctrine\ORM\Mapping\Driver\AttributeDriver; +use Doctrine\Tests\Mocks\AttributeDriverFactory; use Doctrine\Tests\Mocks\EntityManagerMock; use PHPUnit\Framework\TestCase; use Psr\Cache\CacheItemPoolInterface; @@ -22,7 +23,6 @@ use function class_exists; use function method_exists; -use function realpath; use function sprintf; // DBAL 3 compatibility @@ -57,9 +57,10 @@ abstract class OrmTestCase extends TestCase private CacheItemPoolInterface|null $secondLevelCache = null; + /** @param list $paths */ protected function createAttributeDriver(array $paths = []): AttributeDriver { - return new AttributeDriver($paths); + return AttributeDriverFactory::createAttributeDriver($paths); } /** @@ -96,9 +97,7 @@ private function buildTestEntityManagerWithPlatform(Connection $connection): Ent TestUtil::configureProxies($config); $config->setMetadataCache($metadataCache); $config->setQueryCache(self::getSharedQueryCache()); - $config->setMetadataDriverImpl(new AttributeDriver([ - realpath(__DIR__ . '/Models/Cache'), - ], true)); + $config->setMetadataDriverImpl(AttributeDriverFactory::createAttributeDriver([__DIR__ . '/Models/Cache'])); if ($this->isSecondLevelCacheEnabled) { $cacheConfig = new CacheConfiguration();