Doctrine ReflectionException property does not exist - php

I'm trying to add Doctrine on top of an existing database. I let Doctrine generate annotated entities and adjusted from there. When I try to load the entity below I get the error PHP Fatal error: Uncaught exception 'ReflectionException' with message 'Property Users\\User::$resellerID does not exist'
class User
{
/* ... */
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToOne(targetEntity="\Resellers\Reseller")
* #ORM\JoinTable(name="reseller",
* joinColumns={
* #ORM\JoinColumn(name="resellerID", referencedColumnName="resellerID")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="resellerID", referencedColumnName="resellerID")
* }
* )
*/
private $reseller;
/* ... */
}
Both the user and reseller tables have resellerID columns. My understanding is that for joining ID columns you don't add the ID columns as properties in the entity class. So what's causing the ReflectionException?

Since I had renamed the autogenerated property from resellerID to reseller (after trying to use it) it turns out I needed to clear the Doctrine cache.
php vendor/bin/doctrine.php orm:clear-cache:result
php vendor/bin/doctrine.php orm:clear-cache:query
php vendor/bin/doctrine.php orm:clear-cache:metadata
Or, if you are using Symfony with Doctrine:
php bin/console doctrine:cache:clear-result
php bin/console doctrine:cache:clear-query
php bin/console doctrine:cache:clear-metadata

For me clearing the PHP APC cache was the solution
<?php
apc_clear_cache();

Anyway, it helped me
php artisan doctrine:clear:metadata:cache

Usually on production you want something like this:
php bin/console doctrine:cache:clear-result --env=prod
php bin/console doctrine:cache:clear-query --env=prod
php bin/console doctrine:cache:clear-metadata --env=prod

My error still occurred when I attempted to clear the doctrine cache.
What worked for me was to manually clear the cache by deleting the folder under /storage/framework/cache/*

In Symfony, due to Docker container permissions, I had to manually delete everything under /var/cache/.

If anyone is reading this while using a Docker container:
Use Terminal within your PHP/Symfony container.
Enter the doctrine cache clear commands referenced in older answers:
php bin/console doctrine:cache:clear-result
php bin/console doctrine:cache:clear-query
php bin/console doctrine:cache:clear-metadata
Do the APC cache clear also referenced in older answers:
php -r "apc_clear_cache();"
Restart your PHP / Symfony container in Docker.
The restart as a last step ends up clearing whatever is lingering, at least in my case. Hope this helps anyone else using Docker.

Related

Symfony make:entity annotation mapping error

I want to create a new entity in my ORO platform application by using the make:entity command from the MakerBundle.
I expect it to create an entity in my bundle Acme\Bundle\TestBundle which I set in my config_dev.yml by using:
maker:
root_namespace: 'Acme\Bundle\TestBundle'
So I execute
bin/console make:entity Test
which returns
! [NOTE] It looks like your app may be using a namespace other than "Acme\Bundle\TestBundle".
!
! To configure this and make your life easier, see:
! https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html#configuration
created: src/Acme/Bundle/TestBundle/Entity/Test.php
created: src/Acme/Bundle/TestBundle/Repository/TestRepository.php
[ERROR] Only annotation mapping is supported by make:entity, but the
<info>Acme\Bundle\TestBundle\Entity\Test</info> class uses a different format. If you would like
this command to generate the properties & getter/setter methods, add your mapping configuration, and then
re-run this command with the <info>--regenerate</info> flag.
I've tried to run the command once again, which works. But obviously this is not the way how it's meant to work. So how can I fix this mapping error?
I started with the standard Symfony 5 project by using Symfony new myapp.
I add the config file in config/packages/dev/maker.yaml
maker:
root_namespace: 'App\Core'
To generate the entity in the src/Core folder, I got the following error:
➜ symfony console make:entity Post
created: src/Core/Entity/Post.php
created: src/Core/Repository/PostRepository.php
[ERROR] Only annotation mapping is supported by make:entity, but the <info>App\Core\Entity\Post</info> class uses
a different format. If you would like this command to generate the properties & getter/setter methods, add your
mapping configuration, and then re-run this command with the <info>--regenerate</info> flag.
To avoid showing the error in the console, I install the patch created by vklux / maker-bundle-force-annotation
Step 1: install package
composer require cweagans/composer-patches
Step 2: apply the patch in composer.json
{
// {...} composer.json content
"extra": {
"patches": {
"symfony/maker-bundle": {
"Provide flag to force annotation in make entity command": "https://raw.githubusercontent.com/vklux/maker-bundle-force-annotation/master/maker-force-annotation-flag.patch"
}
}
}
}
Step 3: composer update
composer update
Step 4: try make:entity with the additional command option
➜ symfony console make:entity Post --force-annotation
created: src/Core/Entity/Post.php
created: src/Core/Repository/PostRepository.php
Entity generated! Now let's add some fields!
You can always add more fields later manually or by re-running this command.
New property name (press <return> to stop adding fields):
>
✅ 🚀 👍 Everything works fine now.
It's a bug in the doctrine version please try this version good luck
composer req doctrine/doctrine-bundle:2.2
I found a solution to create new entities with Symfony maker using doctrine/doctrine-bundle version higher than 2.2.4
These steps worked for me with:
"doctrine/doctrine-bundle": "^2.7"
PHP 8.1 (I migrate from php 7.4 in my case)
STEP 1: replace type: annotation by type: attribute inside doctrine.yaml
STEP 2: Enter entity root with namespace:
symfony console make:entity App\Entity\test

Doctrine commands not showing up in Symfony 3.4 console even though doctrine/doctrine-bundle is installed

I have an old Symfony 3.4 app (https://github.com/opencfp/opencfp) that needs to have Doctrine added to it so I can replace an existing auth/acl solution with Symfony Guard and then get moving towards upgrading towards Symfony 5. I've installed doctrine/doctrine-bundle and can see that the commands are in the vendor directory but when I run bin/console none of the doctrine commands show up.
Here's what I found when I searched my vendor directory for Doctrine console commands.
doctrine/doctrine-bundle/Resources/config/dbal.xml
87: <tag name="console.command" command="doctrine:database:create" />
93: <tag name="console.command" command="doctrine:database:drop" />
97: <tag name="console.command" command="doctrine:database:import" />
doctrine/doctrine-bundle/Command/Proxy/ImportDoctrineCommand.php
23: ->setName('doctrine:database:import')
doctrine/doctrine-bundle/Command/DropDatabaseDoctrineCommand.php
29: ->setName('doctrine:database:drop')
doctrine/doctrine-bundle/Command/CreateDatabaseDoctrineCommand.php
25: ->setName('doctrine:database:create')
When I run bin/console I don't see any of the commands in the doctrine namespace
Symfony 3.4.35 (kernel: OpenCFP, env: development, debug: true)
Usage:
command [options] [arguments]
Options:
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-e, --env=ENV The Environment name. [default: "development"]
--no-debug Switches off debug mode.
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
about Displays information about the current project
help Displays help for a command
list Lists commands
assets
assets:install Installs bundles web assets under a public directory
cache
cache:clear Clears the cache
cache:pool:clear Clears cache pools
cache:pool:prune Prunes cache pools
cache:warmup Warms up an empty cache
config
config:dump-reference Dumps the default configuration for an extension
debug
debug:autowiring Lists classes/interfaces you can use for autowiring
debug:config Dumps the current configuration for an extension
debug:container Displays current services for an application
debug:event-dispatcher Displays configured listeners for an application
debug:form Displays form type information
debug:router Displays current routes for an application
debug:swiftmailer Displays current mailers for an application
debug:translation Displays translation messages information
debug:twig Shows a list of twig functions, filters, globals and tests
eloquent
eloquent:make:seeder Create a new seeder class
eloquent:migrate Executes a migration.
eloquent:migrate:fresh Drop all tables and re-run all migrations.
eloquent:migrate:install Creates the migration repository.
eloquent:migrate:make Creates a new migration file
eloquent:migrate:refresh Reset and re-run all migrations
eloquent:migrate:reset Rollback all database migrations
eloquent:migrate:rollback Rollback the last database migration
eloquent:migrate:status Show the status of each migration
eloquent:seed Seed the database with records
lint
lint:twig Lints a template and outputs encountered errors
lint:xliff Lints a XLIFF file and outputs encountered errors
lint:yaml Lints a file and outputs encountered errors
router
router:match Helps debug routes by simulating a path info match
server
server:log Starts a log server that displays logs in real time
server:run Runs a local web server
server:start Starts a local web server in the background
server:status Outputs the status of the local web server
server:stop Stops the local web server that was started with the server:start command
swiftmailer
swiftmailer:email:send Send simple email message
swiftmailer:spool:send Sends emails from the spool
translation
translation:update Updates the translation file
user
user:create Creates a new user
user:demote Demote an existing user from a role
user:promote Promote an existing user to a role
I do have some custom commands in there as well.
Any help is greatly appreciated.
From what I gather from vendor/doctrine/doctrine-bundle/DependencyInjection/DoctrineExtension.php, a proper configuration for both the DBAL and the ORM are required to enable the commands:
public function load(array $configs, ContainerBuilder $container)
{
$configuration = $this->getConfiguration($configs, $container);
$config = $this->processConfiguration($configuration, $configs);
$this->adapter->loadServicesConfiguration($container);
if (! empty($config['dbal'])) {
$this->dbalLoad($config['dbal'], $container);
$this->loadMessengerServices($container);
}
if (empty($config['orm'])) {
return;
}
if (empty($config['dbal'])) {
throw new LogicException('Configuring the ORM layer requires to configure the DBAL layer as well.');
}
$this->ormLoad($config['orm'], $container);
}
The ormLoad and dbalLoad are responsible for registering the commands.
In this specific instance, Doctrine needs to be registered:
doctrine:
dbal:
url: mysql://db_user:db_password#127.0.0.1:3306/db_name
orm: ~
The above goes at the end of resources/config/config.yml, or any other file of that folder. Also, you'd need to make the proper adjustments.
doctrine
doctrine:cache:clear-collection-region Clear a second-level cache collection region
doctrine:cache:clear-entity-region Clear a second-level cache entity region
doctrine:cache:clear-metadata Clears all metadata cache for an entity manager
doctrine:cache:clear-query Clears all query cache for an entity manager
doctrine:cache:clear-query-region Clear a second-level cache query region
doctrine:cache:clear-result Clears result cache for an entity manager
doctrine:cache:contains Check if a cache entry exists
doctrine:cache:delete Delete a cache entry
doctrine:cache:flush [doctrine:cache:clear] Flush a given cache
doctrine:cache:stats Get stats on a given cache provider
doctrine:database:create Creates the configured database
doctrine:database:drop Drops the configured database
doctrine:database:import Import SQL file(s) directly to Database.
doctrine:ensure-production-settings Verify that Doctrine is properly configured for a production environment
doctrine:generate:entities [generate:doctrine:entities] Generates entity classes and method stubs from your mapping information
doctrine:mapping:convert [orm:convert:mapping] Convert mapping information between supported formats
doctrine:mapping:import Imports mapping information from an existing database
doctrine:mapping:info
doctrine:query:dql Executes arbitrary DQL directly from the command line
doctrine:query:sql Executes arbitrary SQL directly from the command line.
doctrine:schema:create Executes (or dumps) the SQL needed to generate the database schema
doctrine:schema:drop Executes (or dumps) the SQL needed to drop the current database schema
doctrine:schema:update Executes (or dumps) the SQL needed to update the database schema to match the current mapping metadata
doctrine:schema:validate Validate the mapping files

Codeception & Symfony - run Doctrine migrations before tests

I have a Symfony 4 application and Doctrine with Doctrine migrations. I'm introducing Codeception for running API tests, and need to run migrations before the tests run. Since I'm using the Doctrine2 module I don't really want to be also including the DB module as it's not needed for the tests and would require configuring the test database in two different locations.
I am using the Symfony module currently, and I noticed that the Laravel module has a run_database_migrations configuration option.
What is the best way to handle running the Doctrine migrations command in a Symfony app prior to the tests? (bin/console doctrine:migrations:migrate -n is the specific command).
Edit I've got a solution that, although it works, is nowhere near ideal. By using Codeception Customisation I've created the following extension that basically manually execs the underlying Symfony commands.
class DatabaseMigrationExtension extends Extension
{
public static $events = [
Events::SUITE_BEFORE => 'beforeSuite',
];
public function beforeSuite(SuiteEvent $e)
{
echo(exec('bin/console doctrine:database:drop --force') . PHP_EOL);
echo(exec('bin/console doctrine:database:create') . PHP_EOL);
echo(exec('bin/console doctrine:migrations:migrate -n') . PHP_EOL);
}
}
Edit 2 The goal of this is basically to replicate similar functionality to what the Codeception DB module does, which allows you to provide an SQL dump of a database that it automatically uses in the tests, but instead use Doctrine migrations to handle the DB. - https://codeception.com/docs/modules/Db#sql-data-dump
I spent a while trying a couple of different ways to achieve this. I initially used RunProcess however this seemed to cause sporadic issues with the DB being deleted and not recreated, despite using the sleep configuration. I ended up just updating the existing extension to use the CLI module instead, and it works as desired (without having to create scripts or run multiple commands) and without having to use exec.
Final extension;
class DatabaseMigrationExtension extends Extension
{
public static $events = [
Events::SUITE_BEFORE => 'beforeSuite',
];
public function beforeSuite()
{
try {
/** #var \Codeception\Module\Cli $cli */
$cli = $this->getModule('Cli');
$this->writeln('Recreating the DB...');
$cli->runShellCommand('bin/console doctrine:database:drop --if-exists --force');
$cli->seeResultCodeIs(0);
$cli->runShellCommand('bin/console doctrine:database:create');
$cli->seeResultCodeIs(0);
$this->writeln('Running Doctrine Migrations...');
$cli->runShellCommand('bin/console doctrine:migrations:migrate --no-interaction');
$cli->seeResultCodeIs(0);
$this->writeln('Test database recreated');
} catch (\Exception $e) {
$this->writeln(
sprintf(
'An error occurred whilst rebuilding the test database: %s',
$e->getMessage()
)
);
}
}
}
and registered;
// codeception.yml
extensions:
enabled:
- \DatabaseMigrationExtension
Output (-vv or higher also displays the output of the DB & Migration commands);
I always create a bash script to do this, or a Makefile.
bash command
My ./runtests.sh scripts contains
#!/bin/bash
./bin/console command:for:migrations
./bin/phpunit
Makefile
Same with Makefile
.FOO: testsuite
testsuite:
./runtests.sh
or
.FOO: testsuite
testsuite:
./bin/console command:for:migrations
./bin/phpunit
why I prefer Makefile
Recently I added this script in my .bash_profile that allow me to autocomplete from bash all target made in makefile (very easy because you dont need anymore to remember all commands, but just make and tab).
complete -W "`grep -oE '^[a-zA-Z0-9_.-]+:([^=]|$)' Makefile | sed 's/[^a-zA-Z0-9_.-]*$//'`" make
Thus, .. you can create target like:
runtests
runtests_with_fixtures
migrations
runtests_with_migrations
...
and so on
My suggestion is to create your custom and easy way to run commands.
Here a way to run all or just one command usgin make
.FOO: dropforce
dropforce:
bin/console doctrine:database:drop --force
.FOO: dbcreate
dbcreate:
bin/console doctrine:database:create
.FOO: migrate
migrate:
bin/console doctrine:migrations:migrate
.FOO: suite
suite: dropforce dbcreate migrate
With Codeception 4 you can do it without Cli module:
$symfony = $this->getModule('Symfony');
$symfony->runSymfonyConsoleCommand('doctrine:database:drop',['--if-exists'=>true, '--force'=>true]);
$symfony->runSymfonyConsoleCommand('doctrine:database:create');
$symfony->runSymfonyConsoleCommand('doctrine:migrations:migrate', ['--no-interaction'=>true]);

Symfony2 - "Warning: class_parents(): Class Ambience does not exist and could not be loaded in "

I am trying to create an entity using yml and I am getting the following error:
[ErrorException]
Warning: class_parents(): Class Ambience does not exist and could not be loaded in C:\wamp\www\demo\vendor\gedmo-doctrine-extensions\lib\Gedmo\Mapping\ExtensionMetadataFactory.php line 80
I have created a file named Entities.UserTestDelete.dcm.yml in FooBundle/Resources/config/doctrine/metadata/orm
Contents of file:
Entities\UserTestDelete:
type: entity
table: users
id:
id:
type: integer
generator:
strategy: AUTO
fields:
name:
type: string
length: 50
Then I executed the following command:
php app/console doctrine:mapping:import "DemoFooBundle" yml
And then I got the error. Any idea why would that be a problem?
Just had the same problem ... and managed to solve ...
a var_dump($this) on __contruct of the exception class, in my case:
Symfony\Component\Debug\Exception\ContextErrorException
got me the $message->$trace, which led me to:
vendor/sylius/resource-bundle/EventListener/LoadORMMetadataSubscriber.php
calling function "class_parents"
in function "setAssociationMappings"
So quick fix is to simply comment out the subscribed event:
/**
* #return array
*/
public function getSubscribedEvents()
{
// return array(
// 'loadClassMetadata',
// );
}
now when running "app/console doctrine:mapping:import" again ... there won't be anymore errors ...
also if needed, run the mapping:convert and generate:entities command before enabling / uncommenting the subscribed Event again ...
If you are not using Sylius, try var_dump'ing on your exception class ... there's a good chance you too got some Eventlistner interfering with Doctrine's Import command ...
good luck!
Update
Your first mistake is that you created the yml file. As explained in the cookbook, the doctrine:mapping:import command actually generates the file. Ditch yours, run the command, and let doctrine generate the file itself.
What you do afterwards, is generate the actual entity classes:
php app/console doctrine:mapping:convert annotation ./src
php app/console doctrine:generate:entities DemoFooBundle
If the tables themselves don't exist yet, then you can use these last 2 commands to generate the entities, and then run
php app/console doctrine:schema:update --force
To have doctrine create the tables for you.
A quick look in the cookbook tells me that the bundle name should not be quoted, and that you might want to pass the --force flag to the doctrine:mapping:import command.
It's in the reverse-engineering bit
php app/console doctrine:mapping:import --force DemoFooBundle yml
That's the example Symfony2 cookbook gives, only changed to take yml, instead of xml format.
The error message could also be related to the table name:
table: users
Where the entity is called
class Users
{}
possible related question

Generating a single Entity from existing database using symfony2 and doctrine

Is it possible to generate a single entity from database using the Symfony2 console tool?
In the middle of coding I had to add a table and there are modifications made to the existing entity classes. So I don't want all my entities regenerated.
Any suggestions will be appreciated!
I had the same problem, you've to do this way:
php app/console doctrine:mapping:convert metadata_format \
./src/App/MyBundle/Resources/config/doctrine \
--from-database \
--filter="Yourtablename"
Then
php app/console doctrine:mapping:import AppMyBundle \
metadata_format --filter="Yourtablename"
Where metadata_format is the file ending you want to generate (e.g. xml, yml, annotation)
And finally
php app/console doctrine:generate:entities AppMyBundle --no-backup
Like this doctrine will load only the entity you need. Just be carefull on the filter you must use the CamelCase !
Hope this will help you
For the third command, doctrine kept regenerating all of the Entity files. By adding the entity name after the bundle, it only generated the entity I was interested in.
php app/console doctrine:generate:entities AppMyBundle:Yourtablename --no-backup
Simple Working Solution for Symfony 2.7 option annotation and for [/xml/yml] see http://symfony.com/doc/current/cookbook/doctrine/reverse_engineering.html
do 3 commands in 3 steps:
$ php app/console doctrine:mapping:import --force AppBundle xml --filter="Meeting"
(NOTE: if your database name is my_meeting You will need to change it to MyMeeting in filter="MyMeeting" for doctrine to find your table name. This is because doctrine will always strip underscores and add Camel-case to your table name. If not, you will get this error: "Database does not have any mapping information".)
$ php app/console doctrine:mapping:convert annotation ./src/AppBundle/Entity --from-database --filter="Meeting"
(NOTE: making sure you have namespace AppBundle\Entity; as below in your Meeting.php class file like this:
<?php
/**
* Created by PhpStorm.
* User:
* Date: 03-Sep-2015
* Time: 3:23 PM
*/
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
If not add it in.)
where:
AppBundle is exactly your "AppBundle" in Symfony 2.7
Meeting is the target table (Camel-Case sensitive)
TO BE SURE, check this directory:
src\AppBundle/Resources/config/doctrine/Meeting.orm.xml
AND MAKING SURE you only have .xml files for the table you want to create entity class files and no others. Then run this below command to generate get and set methods for your entity class that you created previously
$ php app/console doctrine:generate:entities AppBundle:Meeting --no-backup
NOTE2:
As the last step you must delete the xml doctrine orm db file in for example src\AppBundle/Resources/config/doctrine/VisitorData.orm.xml
It works very well for me.
For explanation please read: http://symfony.com/doc/current/cookbook/doctrine/reverse_engineering.html
#fyrye's comment that is currently hidden deserves the credit, wanted to add this so it's not missed by others. This is the approach:
/** #var \Doctrine\DBAL\Connection $connection */
$config = $connection->getConfiguration();
// for excluding an specific table
$config->setFilterSchemaAssetsExpression('/^(table_to_reverse_engineer_1|table_to_reverse_engineer_2).*$/');
source: https://coderwall.com/p/jofhdw/doctrine-tell-which-tables-to-work-with
I was having issues when running the following command because of large number of badly defined legacy tables
php ./vendor/bin/doctrine orm:convert-mapping --force --from-database annotation ./src/UI/Entity/
It turns out that the --filter flag only filters AFTER it has read meta data from all of your tables which, if they don't have primary keys or have some other issue, will cause the command to fail
None of the answers were quite right for me using Symfony 3. I ended up doing:
php bin/console doctrine:mapping:import --force MyBundle xml --filter="MyTable"
php bin/console doctrine:mapping:convert annotation ./src --filter="MyTable"
php bin/console doctrine:generate:entities MyBundle:MyTable --path ./src
I would have left this as a comment to the accepted answer but I'm a newbie.
For those like me who had trouble with the --filter switch mapping multiple tables with coincident strings in names, one can use a pattern.
Example table names:
Vendor
VendorContact
php app/console doctrine:mapping:convert metadata_format \
./src/App/MyBundle/Resources/config/doctrine \
--from-database \
--filter="Vendor"
That command will convert both tables rather than just Vendor. If you want just Vendor and not VendorContact, use a pattern in --filter:
php app/console doctrine:mapping:convert metadata_format \
./src/App/MyBundle/Resources/config/doctrine \
--from-database \
--filter="\bVendor\b"
Hope that helps someone!
Works great with Symfony 3 too.
If you are getting "No Metadata Classes to process." message try convert your tablename to Doctrine camel casing in the filter parameter.
"my_table_name" needs to be write as "MyTableName".
--filter works with entity name, not table name !
php bin/console doctrine:mapping:import "App\Entity" annotation --path=config/doctrine --filter="YourEntity"
for Symfony 3
To generate the entities for a new "Group" table
php bin/console doctrine:mapping:import "App\Entity" annotation --path=src/AppBundle/Entity --filter Group
as written in the symfony 3 documentation
I had exactly the same issue with Symfony 2.4 and MySQL.
None of the workarounds posted above worked for me.
I ended up creating a new database with the tables I want to extract (this can be easy to do because MySQL provides the creation script).
Then changed the connection to that new database and executed the entity extraction command from there.
Seems to be a bit radical, but I will not create the entities by hand.
Hope that helps
Didn't work any of these for my symfony 3.3. So I just created a copy of directory and re-generated all of the entities in copy directory. Then I copied required entities in my original directory.
--filter does not work due to this issue https://github.com/symfony/symfony/issues/7717
Since 2019 doctrine has deprecated the reserve-engineering functionality, and it is therefore not recommended to use it any more. Instead, Symfony recommends to use make:entity from the Symfony Maker Bundle instead.

Categories