Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error with doctrine.uuid_generator in doctrine entity #7911

Closed
scope-li opened this issue May 1, 2023 · 3 comments
Closed

Error with doctrine.uuid_generator in doctrine entity #7911

scope-li opened this issue May 1, 2023 · 3 comments
Assignees

Comments

@scope-li
Copy link

scope-li commented May 1, 2023

Description
If I use the following in a Doctrine Entity for the ID (via Trait, based by https://symfony.com/doc/current/components/uid.html#storing-uuids-in-databases):

trait EntityTrait
{
    #[ORM\Id]
    #[ORM\Column(type: UuidType::NAME, unique: true)]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator("doctrine.uuid_generator")]
    private ?string $id = null;

   ...
}

i get the following error message with --debug:

[ERROR] Could not process "/Users/user/Code/src/Repository/CheckerRepository.php" file, due to: 
         "System error: "Cannot instantiate custom generator : array (                                                  
           'class' => 'doctrine.uuid_generator',                                                                        
         )"                                                                                                             
                                                                                                                        
         Stack trace:                                                                                                   
         #0 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(652):                                 
         Doctrine\ORM\Mapping\Exception\InvalidCustomGenerator::onMissingClass(Array)                                   
         #1 vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(143):                                 
         Doctrine\ORM\Mapping\ClassMetadataFactory->completeIdGeneratorMapping(Object(Doctrine\ORM\Mapping\ClassMetadat 
         a))                                                                                                            
         #2 vendor/doctrine/persistence/src/Persistence/Mapping/AbstractClassMetadataFactory.php(415):                  
         Doctrine\ORM\Mapping\ClassMetadataFactory->doLoadMetadata(Object(Doctrine\ORM\Mapping\ClassMetadata), NULL,    
         false, Array)                                                                                                  
         #3 vendor/doctrine/persistence/src/Persistence/Mapping/AbstractClassMetadataFactory.php(300):                  
         Doctrine\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata('App\\Entity\\Chec...')                
         #4 vendor/phpstan/phpstan-doctrine/src/Type/Doctrine/ObjectMetadataResolver.php(123):                          
         Doctrine\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor('App\\Entity\\Chec...')              
         #5 vendor/phpstan/phpstan-doctrine/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php(149):         
         PHPStan\Type\Doctrine\ObjectMetadataResolver->getClassMetadata('App\\Entity\\Chec...')                         
         #6 vendor/phpstan/phpstan-doctrine/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php(107):         
         PHPStan\Type\Doctrine\GetRepositoryDynamicReturnTypeExtension->getRepositoryClass('App\\Entity\\Chec...',      
         'Doctrine\\ORM\\En...')                                                                                        
         #7 phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(3344):       
         PHPStan\Type\Doctrine\GetRepositoryDynamicReturnTypeExtension->getTypeFromMethodCall(Object(PHPStan\Reflection 
         \ResolvedMethodReflection), Object(PhpParser\Node\Expr\MethodCall), Object(PHPStan\Analyser\MutatingScope))    
         #8 phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(1333):       
         PHPStan\Analyser\MutatingScope->methodCallReturnType(Object(PHPStan\Type\ObjectType), 'getRepository',         
         Object(PhpParser\Node\Expr\MethodCall))                                                                        
         #9 phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(1339):       
         PHPStan\Analyser\MutatingScope->PHPStan\Analyser\{closure}()                                                   
         #10 phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(556):       
         PHPStan\Analyser\MutatingScope->resolveType('$this->getEntit...', Object(PhpParser\Node\Expr\MethodCall))      
         #11 phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(742):       
         PHPStan\Analyser\MutatingScope->getType(Object(PhpParser\Node\Expr\MethodCall))                                
         #12 phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(556):       
         PHPStan\Analyser\MutatingScope->resolveType('$repo = $this->...', Object(PhpParser\Node\Expr\Assign))          
         #13 phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(1473):  
         PHPStan\Analyser\MutatingScope->getType(Object(PhpParser\Node\Expr\Assign))                                    
         #14 phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(567):   
         PHPStan\Analyser\NodeScopeResolver->findEarlyTerminatingExpr(Object(PhpParser\Node\Expr\Assign),               
         Object(PHPStan\Analyser\MutatingScope))                                                                        
         #15 phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(362):   
         PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Expression),                    
         Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))            
         #16 phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(531):   
         PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\ClassMethod), Array,           
         Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))            
         #17 phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(362):   
         PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\ClassMethod),                   
         Object(PHPStan\Analyser\MutatingScope), Object(PHPStan\Node\ClassStatementsGatherer),                          
         Object(PHPStan\Analyser\StatementContext))                                                                     
         #18 phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(609):   
         PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\Class_), Array,                
         Object(PHPStan\Analyser\MutatingScope), Object(PHPStan\Node\ClassStatementsGatherer),                          
         Object(PHPStan\Analyser\StatementContext))                                                                     
         #19 phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(362):   
         PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Class_),                        
         Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))            
         #20 phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(581):   
         PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\Namespace_), Array,            
         Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))            
         #21 phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(331):   
         PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Namespace_),                    
         Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))            
         #22 vendor/rector/rector/packages/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php(327):            
         PHPStan\Analyser\NodeScopeResolver->processNodes(Array, Object(PHPStan\Analyser\MutatingScope),                
         Object(Closure))                                                                                               
         #23 vendor/rector/rector/packages/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php(214):            
         Rector\NodeTypeResolver\PHPStan\Scope\PHPStanNodeScopeResolver->processNodesWithDependentFiles('/Users/user 
         l...', Array, Object(PHPStan\Analyser\MutatingScope), Object(Closure))                                         
         #24 vendor/rector/rector/packages/NodeTypeResolver/NodeScopeAndMetadataDecorator.php(41):                      
         Rector\NodeTypeResolver\PHPStan\Scope\PHPStanNodeScopeResolver->processNodes(Array, '/Users/user...')      
         #25 vendor/rector/rector/src/Application/FileProcessor.php(54):                                                
         Rector\NodeTypeResolver\NodeScopeAndMetadataDecorator->decorateNodesFromFile(Object(Rector\Core\ValueObject\Ap 
         plication\File), Array)                                                                                        
         #26 vendor/rector/rector/src/Application/FileProcessor/PhpFileProcessor.php(143):                              
         Rector\Core\Application\FileProcessor->parseFileInfoToLocalCache(Object(Rector\Core\ValueObject\Application\Fi 
         le))                                                                                                           
         #27 vendor/rector/rector/src/Application/FileProcessor/PhpFileProcessor.php(97):                               
         Rector\Core\Application\FileProcessor\PhpFileProcessor->parseFileAndDecorateNodes(Object(Rector\Core\ValueObje 
         ct\Application\File))                                                                                          
         #28 vendor/rector/rector/packages/Parallel/WorkerRunner.php(130):                                              
         Rector\Core\Application\FileProcessor\PhpFileProcessor->process(Object(Rector\Core\ValueObject\Application\Fil 
         e), Object(Rector\Core\ValueObject\Configuration))                                                             
         #29 vendor/rector/rector/packages/Parallel/WorkerRunner.php(106):                                              
         Rector\Parallel\WorkerRunner->processFiles(Object(Rector\Core\ValueObject\Application\File),                   
         Object(Rector\Core\ValueObject\Configuration), Array)                                                          
         #30 vendor/rector/rector/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):                   
         Rector\Parallel\WorkerRunner->Rector\Parallel\{closure}(Array)                                                 
         #31 vendor/rector/rector/vendor/clue/ndjson-react/src/Decoder.php(117):                                        
         RectorPrefix202304\Evenement\EventEmitter->emit('data', Array)                                                 
         #32 vendor/rector/rector/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):                   
         RectorPrefix202304\Clue\React\NDJson\Decoder->handleData(Array)                                                
         #33 vendor/rector/rector/vendor/react/stream/src/Util.php(62):                                                 
         RectorPrefix202304\Evenement\EventEmitter->emit('data', Array)                                                 
         #34 vendor/rector/rector/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):                   
         RectorPrefix202304\React\Stream\Util::RectorPrefix202304\React\Stream\{closure}('{"action":"main...')          
         #35 vendor/rector/rector/vendor/react/stream/src/DuplexResourceStream.php(154):                                
         RectorPrefix202304\Evenement\EventEmitter->emit('data', Array)                                                 
         #36 vendor/rector/rector/vendor/react/event-loop/src/StreamSelectLoop.php(201):                                
         RectorPrefix202304\React\Stream\DuplexResourceStream->handleData(Resource id #3429)                            
         #37 vendor/rector/rector/vendor/react/event-loop/src/StreamSelectLoop.php(173):                                
         RectorPrefix202304\React\EventLoop\StreamSelectLoop->waitForStreamActivity(NULL)                               
         #38 vendor/rector/rector/src/Console/Command/WorkerCommand.php(63):                                            
         RectorPrefix202304\React\EventLoop\StreamSelectLoop->run()                                                     
         #39 vendor/rector/rector/vendor/symfony/console/Command/Command.php(311):                                      
         Rector\Core\Console\Command\WorkerCommand->execute(Object(RectorPrefix202304\Symfony\Component\Console\Input\A 
         rgvInput), Object(RectorPrefix202304\Symfony\Component\Console\Output\ConsoleOutput))                          
         #40 vendor/rector/rector/vendor/symfony/console/Application.php(899):                                          
         RectorPrefix202304\Symfony\Component\Console\Command\Command->run(Object(RectorPrefix202304\Symfony\Component\ 
         Console\Input\ArgvInput), Object(RectorPrefix202304\Symfony\Component\Console\Output\ConsoleOutput))           
         #41 vendor/rector/rector/vendor/symfony/console/Application.php(320):                                          
         RectorPrefix202304\Symfony\Component\Console\Application->doRunCommand(Object(Rector\Core\Console\Command\Work 
         erCommand), Object(RectorPrefix202304\Symfony\Component\Console\Input\ArgvInput),                              
         Object(RectorPrefix202304\Symfony\Component\Console\Output\ConsoleOutput))                                     
         #42 vendor/rector/rector/src/Console/ConsoleApplication.php(49):                                               
         RectorPrefix202304\Symfony\Component\Console\Application->doRun(Object(RectorPrefix202304\Symfony\Component\Co 
         nsole\Input\ArgvInput), Object(RectorPrefix202304\Symfony\Component\Console\Output\ConsoleOutput))             
         #43 vendor/rector/rector/vendor/symfony/console/Application.php(206):                                          
         Rector\Core\Console\ConsoleApplication->doRun(Object(RectorPrefix202304\Symfony\Component\Console\Input\ArgvIn 
         put), Object(RectorPrefix202304\Symfony\Component\Console\Output\ConsoleOutput))                               
         #44 vendor/rector/rector/bin/rector.php(128): RectorPrefix202304\Symfony\Component\Console\Application->run()  
         #45 vendor/rector/rector/bin/rector(5): require_once('/Users/user...')                                     
         #46 vendor/bin/rector(120): include('/Users/user...')                                                      
         #47 {main}". On line: 22

Reproduction
See https://github.com/scope-li/sulu_rector_uuid_generator_reproducer
composer install && vendor/bin/rector process src --dry-run --debug

Findings
The error occurs when I define a method in the repository that starts with find, which is a prefix for certain Magic methods in the Doctrine repository (see https://github.com/scope-li/sulu_rector_uuid_generator_reproducer/blob/main/src/Repository/ContentRepository.php#L42).
The strange thing is that this leads to an error with doctrine.uuid_generator in the ID definition in the entity.
If I choose a method name that does not start with find or use the class name UuidGenerator::class instead of the service name doctrine.uuid_generator it works (see https://github.com/scope-li/sulu_rector_uuid_generator_reproducer/blob/main/src/Entity/Content.php#L17).
But I have to use doctrine.uuid_generator instead of UuidGenerator::class so that the setting for UUID v4 is valid and not v6 is created.

@TomasVotruba TomasVotruba self-assigned this Jul 20, 2023
@TomasVotruba
Copy link
Member

Thanks for reporting and reproducible repositry, I'm looking into this 👍

@TomasVotruba
Copy link
Member

TomasVotruba commented Jul 20, 2023

The exception is thrown inside Doctrine itself, as the provided "class" cannot be a string. We cannot do anything about it in Rector.

It must be class that exists, see:

https://github.com/doctrine/orm/blob/f7e4b61459692f9b747f40696e6bf72080390f2d/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php#L714-L725

I don't use these so not sure what way Doctrine + Symfony is expected :)
But I assume it must be fixed to a real existing class or service name without class: but another keyword.


What helped me locally to make Rector pass was this:

    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: UuidGenerator::class)]
    private ?string $id = null;

@SiebeVE
Copy link

SiebeVE commented Nov 7, 2023

Hi!
Changing it to the class isn't the same. The string references the service, the other the class: see symfony/symfony-docs#18427 (review).
Is it possible to add an extra object manager to rector such as in phpstan?
phpstan/phpstan-doctrine#297 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants