doctrine / DoctrineModule

Doctrine Module for Laminas
http://www.doctrine-project.org/projects/doctrine-module.html
MIT License
398 stars 269 forks source link

Problem with cache factory after update to DoctrineModule 2.x #657

Closed sfurionix closed 4 years ago

sfurionix commented 6 years ago

The service manager cannot create an instance for Doctrine\Common\Cache\FilesystemCache and other cache file drivers. Fatal error: Uncaught Zend\ServiceManager\Exception\ServiceNotFoundException: Unable to create service "Doctrine\Common\Cache\FilesystemCache"; unable to resolve parameter "directory" to a class, interface, or array type in vendor\zendframework\zend-servicemanager\src\AbstractFactory\ReflectionBasedAbstractFactory.php:207 Stack trace: #0 vendor\zendframework\zend-servicemanager\src\AbstractFactory\ReflectionBasedAbstractFactory.php(185): Zend\ServiceManager\AbstractFactory\ReflectionBasedAbstractFactory->resolveParameter(Object(ReflectionParameter), Object(Zend\ServiceManager\ServiceManager), 'Doctrine\\Common...') #1 [internal function]: Zend\ServiceManager\AbstractFactory\ReflectionBasedAbstractFactory->Zend\ServiceManager\AbstractFactory\{closure}(Object(ReflectionParameter)) #2 vendor\zendframework\zend-servicemanager\src\AbstractFactory\ReflectionBasedAbstractFactory.php(127): array_map(Object(Closure), Array) #3 in vendor\zendframework\zend-servicemanager\src\AbstractFactory\ReflectionBasedAbstractFactory.php on line 207

I use the standard doctrine configuration:

'doctrine' => [
    'configuration' => [
        'orm_default' => [
            'metadata_cache' => 'filesystem',
            'query_cache' => 'filesystem',
            'result_cache' => 'filesystem',
            'hydration_cache' => 'filesystem',
        ],
    ],
],

In version 1.2.0 this works correctly, but in 2.x was added checking in doctrine-module/src/DoctrineModule/Service/CacheFactory.php:44

if ($container->has($class)) {
       $cache = $container->get($class);
 } else {

Without this condition, everything works fine.

fri0z commented 4 years ago

Same problem. Occurs when there is a ReflectionBasedAbstractFactory in container. @TomHAnderson pay attention to this issue

TomHAnderson commented 4 years ago

This plainly reads there is a problem with the FilesystemCache and the directory to store configuration does not exist.

Fatal error: Uncaught Zend\ServiceManager\Exception\ServiceNotFoundException: Unable to create service "Doctrine\Common\Cache\FilesystemCache"; unable to resolve parameter "directory" to a class, interface, or array type in vendor\zendframework\zend-servicemanager\src\AbstractFactory\ReflectionBasedAbstractFactory.php:207

Here is the configuration you need to include:

$config = [
    'doctrine' => [
        'cache => [
            'filesystem]' => [
                    'class' => 'Doctrine\Common\Cache\FilesystemCache',
                    'directory' => 'data/DoctrineModule/cache',
                    'namespace' => 'DoctrineModule',
            ],
        ],
    ],
];
fri0z commented 4 years ago

This configuration was specified in the configuration file. The path to the directory was specified correctly (checked several times). The directory is physically present. The rights to the directory are specified 0777

TomHAnderson commented 4 years ago

Perhaps filesystem cache configuration is the wrong config. The switch statement here: https://github.com/doctrine/DoctrineModule/blob/master/src/DoctrineModule/Service/CacheFactory.php#L47 can tell you what type of cache you are creating.

Put a break on line 47 and move the switch down a line or two:

die('cache class: ' . $class);
fri0z commented 4 years ago

In my case I get to the section https://github.com/doctrine/DoctrineModule/blob/master/src/DoctrineModule/Service/CacheFactory.php#L45

Since the condition $container->has ($class) returns a positive result.

TomHAnderson commented 4 years ago

I do not consider this to be a problem with Doctrine.

As you can see here: https://github.com/zendframework/zend-servicemanager/blob/master/src/AbstractFactory/ReflectionBasedAbstractFactory.php#L135

the abstract factory' canCreate function is very weak. I think you need to take the ReflectionBasedAbstractFactory out of the service manager configuration as an Abstract Factory and move your services to:

'service_manager' => [
      'factories' => [
          MyClassWithDependencies::class => ReflectionBasedAbstractFactory::class,
      ],
  ],

Using the abstract factory in this manner is fine grained.

fri0z commented 4 years ago

The factory's abstract canCreate function is really very weak. But I don't really understand why the cachefactory factory tries to call FilesystemCache via Container? And when checking the existence of the service in the content, it gets a positive result? But the service Manager does not specify how to create this service.

TomHAnderson commented 4 years ago

You need a deeper understanding of the service manager.

When a factory of any type says it can create an object that's the end of the service manager search for the proper factory.

I've given you the correct solution in my immediate previous post and this is not Doctrine related so I'm closing this issue. If you still need help post in the service manager, the proper, repository' issues.