I have changed the configuration of my Symfony project to use PHP attributes with Doctrine in my Entities. I was really happy about this and wanted to give it a try.
I have changed my doctrine.yaml from annotation to attribute
orm:
auto_generate_proxy_classes: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
mappings:
App:
is_bundle: false
type: attribute
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
and use attributes in my entities
#[ORM\Entity(UserRepository::class)]
class User implements UserInterface
{
#[ORM\Id()]
#[ORM\GeneratedValue()]
#[ORM\Column(type: "integer")]
private ?int $id;
#[ORM\Column(type: "string", length: 180, unique: true)]
private ?string $email;
#[ORM\Column(type: "json")]
private array $roles = [];
}
With this configuration my php bin/console do:sc:up -f works well.
But when I try to generate a new entity with php bin/console make:entity I get this error:
[ERROR] Only annotation mapping is supported by make:entity, but the
App\Entity\Toto 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 --regenerate flag.
It seems like it's not possible yet to use maker to generate entity with attribute.
Does anyone have found a way to fix this issue or do we just have to wait a new release?
For now I'm using:
"doctrine/annotations": "1.13.1"
"doctrine/doctrine-bundle": "2.4.2",
"doctrine/orm": "2.9.3"
"symfony/maker-bundle": "1.31.1",
Currently, it's not supported. There is an issue created asking for this, although I'm 120% sure that the developers already know about PHP attributes, and this feature will get done whenever possible.
In the meantime, you can create your entities manually, without using maker (not that hard), or even use something like Rector to convert Annotations to Attributes. There is a built-in rule for that.
Related
I was using Gedmo\Blameable with the Stof\DoctrineExtensionsBundle and everything was working great with the following config:
# config/packages/stof_doctrine_extensions.yaml
stof_doctrine_extensions:
default_locale: en_US
orm:
default:
blameable : true
timestampable: true
Later I had a need to have a console command add a record so looked for the applicable services:
$ bin/console debug:container | grep blame
stof_doctrine_extensions.event_listener.blame Stof\DoctrineExtensionsBundle\EventListener\BlameListener
stof_doctrine_extensions.listener.blameable Gedmo\Blameable\BlameableListener
injected the service into my command:
services:
App\Command\ClassThatAddsRecord:
arguments:
$blameableListener: '#stof_doctrine_extensions.listener.blameable'
and called it:
class ClassThatAddsRecord extends Command
{
public function __construct(private BlameableListener $blameableListener)
{
parent::__construct();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
// ...
$this->blameableListener->setUserValue($user);
}
}
But then I changed to database-less tokens and thus changed the user provider to return App\Security\User instead of App\Entity\User, gave it a try, and CRASH, Doctrine complained about the user not being in the chain configured namespaces. Looking at Stof\DoctrineExtensionsBundle\EventListener\BlameListener, I see it is being inected with Gedmo\Blameable\BlameableListener and executes $this->blameableListener->setUserValue($token->getUser()), and since $token->getUser() is not an Doctrine entity, I am getting the error.
So, looking at the docs, I see I can override the listener and changed the config to the following:
stof_doctrine_extensions:
default_locale: en_US
class:
blameable: App\EventListener\MyBlameableListener
orm:
default:
blameable : true
timestampable: true
But now when I check my services, I know longer have Gedmo\Blameable\BlameableListener which I need but only Stof\DoctrineExtensionsBundle\EventListener\BlameListener which I don't want.
$ bin/console debug:container | grep blame
app.blame_listner App\EventListener\MyBlameableListener
stof_doctrine_extensions.event_listener.blame Stof\DoctrineExtensionsBundle\EventListener\BlameListener
stof_doctrine_extensions.listener.blameable App\EventListener\BlameListener
How can I use my own blameable listner?
Hello, i need to explain what i'm was doing at first:
I was on a project and for some reason I ended up having to use two databases instead of just one. so i do what it was needed to do, i change my doctrine.yaml settings with what is explain in the symfony doc and in that moment the error appeared
An SQL error that says that it was no column found for X request on X table
(the error is SQLSTATE[42S02], but it's not important)
(in parallel of that error i need to say that the "--em" shit didn't work for me when i do php bin/console doctrine:migrations:diff/migrate --em=default or customer so i does indeed php bin/console doctrine:schema:update --force --em=default or customer and i don't know why ! so if you have something to say here i'll take it too.)
Anyway i go back to what i was explaining,
This sql error appear because of my controller, they working with default Repository implementation (MyClassNameRepository $myClasNameReposiotry for an exemple) that was normaly implement the default EntityManager but it doesn't and that throw this error.
At this point i though that i had an error in some files in symfony because of a shit i probably does. I don't have the time for replacing all the repository implementation, soo i create a new project with the doctrine config that is needed for working with two database according to the symfony doc. Is the same as the One in my project :
doctrine:
dbal:
default_connection: default
connections:
default:
# configure these for your database server
url: '%env(resolve:DATABASE_URL)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
customer:
# configure these for your database server
url: '%env(resolve:DATABASE_CUSTOMER_URL)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
orm:
entity_managers:
default:
connection: default
mappings:
Main:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: Main
customer:
connection: customer
mappings:
Customer:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Customer'
prefix: 'App\Entity\Customer'
alias: Customer
That is the same config than the one in symfony doc except for the Main dir.
i created my entities, one in each database and i does a crud on them.
The Hierarchy files:
src/
-----Entity/
----Product
----Customer/
-ProductCustomer
-----Repository/
----ProductRepository
----Customer/
-----ProductCustomerRepository
And same for the form
And with this testApplication i saw a new error, for the customer part i had the same sql error, because the column was searched in the wrong bdd, after changing the code for :
this
/**
* #Route("/", name="customer_produit_customer_index", methods={"GET"})
*/
public function index(ProductCustomerRepository $productCustomerRepository): Response
{
return $this->render('customer/produit_customer/index.html.twig', [
'produit_customers' => $productCustomerRepository->findAll(),
]);
}
to this
/**
* #Route("/", name="customer_produit_customer_index", methods={"GET"})
*/
public function index(): Response
{
$productCustomers = $this->getDoctrine()
->getRepository(ProduitCustomerRepository::class, "customer")
->findAll()
;
return $this->render('customer/produit_customer/index.html.twig', [
'produit_customers' => $productCustomers,
]);
}
The error has changed, as I expected and know i have :
The class 'App\Repository\Customer\ProduitCustomerRepository' was not found in the chain configured namespaces App\Entity\Customer
No matter how much I search the internet, I can't find anything that really solves my mistakes. Now I'm tired of looking, especially since I don't understand these errors because it's not the first time I've set up an application connected to two databases, but it's the first time that I have these errors.
So please help me =D.
I have generated an entity named 'MyEntity' with annotation type mapping information using the doctrine:mapping:convert command with the --from-database option.
The entity is in a non-satandard folder which is defined in the doctrine ORM configuration as:
doctrine:
orm:
entity_managers:
default:
MyEntity:
mapping: true
type: annotation
dir: '%kernel.root_dir%/../src/Path/To/Entity'
prefix: 'Path\To\Entity'
is_bundle: false
The class appears in the appropriate directory and has all of the correct properties and annotations however when I try to use the doctrine:migrations:diff command the outcome is a migration that drops the table that the entity was generated from in the first place. This seems to imply that the mapping information generated by the doctrine:mapping:convert command is not being picked up by the doctrine:migrations:diff command. Any insight on this issue would br greatly appreciated.
After returning to the problem I noticed that the generated entity class was in the global namespace as opposed to the one specified by the config file, correcting this immediately fixed the problem.
This is my orm config for my Doctrine in Symfony2
orm:
default_entity_manager: default
auto_generate_proxy_classes: false
entity_managers:
default:
connection: default
auto_mapping: false
mappings:
MyMappings:
type: yml
is_bundle: false
dir: %kernel.root_dir%/../src/Bundle/Entity/orm
prefix: Bundle\Entity
My directory structure is set up like this:
src
-- Bundle
--- Entity
---- orm
----- Bundle.Entity.(TableName).orm.yml
My question is why when I run:
php app/console doctrine:generate:entities MyMappings
I would get the following exception:
php app/console doctrine:generate:entities MyMappings
[Doctrine\Common\Persistence\Mapping\MappingException]
Invalid mapping file 'Bundle.Entity.(TableName).orm.yml' for class 'Bundle\Entity\(TableName)'
the orm files were named (TableName).orm.yml
And the yml:
TableName:
type: entity
When I used the import from database I added the namespace:
php app/console doctrine:mapping:convert yml ./src/Bundle/Entity/orm --force --from-database --namespace="Bundle\\Entity\\"
which generated the Bundle.Entity.(TableName).orm.yml files.
And the yml:
Bundle\Entity\TableName:
type: entity
Now, I keep getting
[Doctrine\Common\Persistence\Mapping\MappingException]
Invalid mapping file 'Bundle.Entity.Bundle.Entity.(TableName).orm.yml' for class 'Bundle\Entity\Bundle\Entity\(TableName)'
I feel like I am missing something obvious as to how to properly generate these entities in the correct namespace. If I am not clear please let me know and I will try to rephrase this issue.
More Information:
I am trying to generate these entities in a non-bundle namespace
After creating entity with:
php app/console doctrine:generate:entity
and while using:
php app/console doctrine:schema:update --force
I encountered:
No Metadata Classes to process.
Entity
namespace ISLab\AdminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="menu_items")
*/
class MenuItem
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(name="parent", type="integer")
*/
private $parent;
// ...
}
I had a similar problem and took me a while until I find out how to clear out the cache. Clearing only doctrine's cache did not work for me. Use the command below to clear the entire environment (production one in this case)
php app/console cache:clear --env=prod
I had the same problem when I generate an Entity through the interactive generator from command line. When I first created I set the Configuration Format to PHP and that didn't work. So I deleted it and tried again but this time I selected format = annotation. Then it worked! Maybe this could solve someone's problem.
So entity manager didn't create metadata for your entity. Here are things I would check first:
Clear your cache
Make sure your AdminBundle is registered in AppKernel.
Make sure that entity manager's automapping is true. Or set it up correctly if you're using custom EM.
A bit offtopic:
I see you're making a menu system and I would strongly suggest you to check out Doctrine Extensions Tree which should allow you to query and edit items much more efficiently than with your structure.
I had the same problem when i update the database.
So i follow this solution and i tried to adapt in my case and it works.
I think that is a problem of automapping indeed also with auto_mapping setted true, symfony wasn't able to find the entities.
I hope that it can help.
orm:
auto_generate_proxy_classes: "%kernel.debug%"
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
mappings:
AppBundle:
type: annotation
is_bundle: false
dir: %kernel.root_dir%/../src/AppBundle/Entity/
prefix: AppBundle\Entity
alias: AppBundle
for anyone on the same thing, these are few steps to go:
1. Clear the cache:
bin/console c:c --env=dev
bin/console c:c --env=prod
If you see any errors meanwhile, try to cover it by inspecting source of problem.
2. Inspect your configuration:
According to this sample directory structure:
Application
|
└- src
|
└- Acme
|
└- Bundle
|
└- BlogBundle
|
└- Model
|
└- Entity
You should have this configuration inside your app/config/config.yml file:
doctrine:
...
orm:
auto_generate_proxy_classes: '%kernel.debug%'
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
mappings:
AcmeBlogBundle:
mapping: true
type: annotation
dir: Model/Entity
alias: Blog
prefix: Acme\Bundle\BlogBundle\Model\Entity
is_bundle: true
3. Update your database schema:
You can now update your database schema without any problems:
bin/console doctrine:schema:update
despite of this being the final step for most cases, you may still use --verbose to find any further possible problems.
bin/console doctrine:schema:update --verbose
Make sure your entities are placed in your bundle's Entity directory. In my case they were in Entities instead.
For me generating all the entities from the cmd did the work.
In my case, i solve the problem creating the Entity folder. For some reason it had been eliminated. I hope that it can help.
I've had the same issue. For me it was that my directory called 'Entity' was not in the 'AppBundle' but in the 'src' directory. Moving the 'Entity' directory into the 'AppBundle' directory fixed the problem for me!