{"record":{"id":"a03f87d4fb17b3d9","repo":"doctrine/orm","slug":"if-you-want-to-use-a-read-write-cache-an-impleme","errorCode":null,"errorMessage":"If you want to use a \"READ_WRITE\" cache an implementation of \"Doctrine\\ORM\\Cache\\ConcurrentRegion\" is required, The default implementation provided by doctrine is \"Doctrine\\ORM\\Cache\\Region\\FileLockRegion\" if you want to use it please provide a valid directory, DefaultCacheFactory#setFileLockRegionDirectory(). ","messagePattern":"If you want to use a \"READ_WRITE\" cache an implementation of \"Doctrine\\\\ORM\\\\Cache\\\\ConcurrentRegion\" is required, The default implementation provided by doctrine is \"Doctrine\\\\ORM\\\\Cache\\\\Region\\\\FileLockRegion\" if you want to use it please provide a valid directory, DefaultCacheFactory#setFileLockRegionDirectory\\(\\)\\. ","errorType":"exception","errorClass":"LogicException","httpStatus":null,"severity":"error","filePath":"src/Cache/DefaultCacheFactory.php","lineNumber":160,"sourceCode":"    /**\n     * {@inheritDoc}\n     */\n    public function getRegion(array $cache): Region\n    {\n        if (isset($this->regions[$cache['region']])) {\n            return $this->regions[$cache['region']];\n        }\n\n        $name     = $cache['region'];\n        $lifetime = $this->regionsConfig->getLifetime($cache['region']);\n        $region   = new DefaultRegion($name, $this->cacheItemPool, $lifetime);\n\n        if ($cache['usage'] === ClassMetadata::CACHE_USAGE_READ_WRITE) {\n            if (\n                $this->fileLockRegionDirectory === '' ||\n                $this->fileLockRegionDirectory === null\n            ) {\n                throw new LogicException(\n                    'If you want to use a \"READ_WRITE\" cache an implementation of \"Doctrine\\ORM\\Cache\\ConcurrentRegion\" is required, ' .\n                    'The default implementation provided by doctrine is \"Doctrine\\ORM\\Cache\\Region\\FileLockRegion\" if you want to use it please provide a valid directory, DefaultCacheFactory#setFileLockRegionDirectory(). ',\n                );\n            }\n\n            $directory = $this->fileLockRegionDirectory . DIRECTORY_SEPARATOR . $cache['region'];\n            $region    = new FileLockRegion($region, $directory, (string) $this->regionsConfig->getLockLifetime($cache['region']));\n        }\n\n        return $this->regions[$cache['region']] = $region;\n    }\n\n    public function getTimestampRegion(): TimestampRegion\n    {\n        if ($this->timestampRegion === null) {\n            $name     = Cache::DEFAULT_TIMESTAMP_REGION_NAME;\n            $lifetime = $this->regionsConfig->getLifetime($name);\n","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/doctrine/orm/blob/d9b9ff73016bf598ae07515f97289ce8074e97a5/src/Cache/DefaultCacheFactory.php#L142-L178","documentation":"LogicException from DefaultCacheFactory::getRegion() (src/Cache/DefaultCacheFactory.php:160). Something is cached with usage READ_WRITE, and the default factory implements READ_WRITE locking via FileLockRegion — but no lock directory was configured, so it cannot build the required ConcurrentRegion and refuses to fall back to an unlocked region (which would silently break consistency).","triggerScenarios":"Any entity or association mapped with `#[Cache(usage: 'READ_WRITE')]` (second-level cache enabled) while DefaultCacheFactory::setFileLockRegionDirectory() was never called or was called with '' — the factory's $fileLockRegionDirectory is null/empty when the region is first requested.","commonSituations":"Enabling the second-level cache in a new project and copying `usage: READ_WRITE` from docs without configuring the lock directory; Symfony doctrine-bundle setups missing the file_lock_region_directory setting; turning on SLI cache after an upgrade where the directory config lived in removed bootstrap code.","solutions":["Call $cacheFactory->setFileLockRegionDirectory('/var/cache/app/doctrine-lock') (a writable, preferably local, path) before the entity manager is used — regions are built lazily and memoized, so configure it in the factory bootstrap.","In Symfony with doctrine-bundle, set the second-level-cache file lock region directory option (doctrine.orm.second_level_cache.file_lock_region_directory) instead of hand-calling the factory.","If strict locking is unnecessary, change usage to NONSTRICT_READ_WRITE, which needs no lock directory.","Keep the directory out of the project root and exclude it from deployments/rsync so lock files do not leak between releases."],"exampleFix":"// before\n$factory = new DefaultCacheFactory($regionsConfig, $cacheItemPool);\n$ormConfig->setSecondLevelCacheEnabled(true);\n// entity has #[Cache(usage: 'READ_WRITE')] -> LogicException at runtime\n\n// after\n$factory = new DefaultCacheFactory($regionsConfig, $cacheItemPool);\n$factory->setFileLockRegionDirectory(sys_get_temp_dir() . '/doctrine-slc-lock');\n$ormConfig->setSecondLevelCacheEnabled(true);\n$ormConfig->getSecondLevelCacheConfiguration()->setCacheFactory($factory);","handlingStrategy":"validation","validationCode":"$factory = new DefaultCacheFactory($regionsConfig, $pool);\nif ($anyReadWriteUsage) {\n    $dir = sys_get_temp_dir() . '/doctrine-slc-lock';\n    if (! is_dir($dir)) { mkdir($dir, 0775, true); }\n    $factory->setFileLockRegionDirectory($dir);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat setFileLockRegionDirectory() as mandatory config whenever READ_WRITE appears in mappings.","Default to NONSTRICT_READ_WRITE in shared examples/docs unless locking is configured.","Assert during bootstrap: if any metadata uses READ_WRITE, the lock directory must be set and writable."],"tags":["doctrine-orm","second-level-cache","read-write-cache","configuration"],"backgroundTag":"missing-file-lock-region-directory","analyzedSha":"d9b9ff73016bf598ae07515f97289ce8074e97a5","analyzedAt":"2026-08-21T06:13:15.863Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}