I got this error
MappingException: The class 'Telnet\IPBBridgeBundle\Entity\Member' was not found in the chain configured namespaces Telnet\CSSBundle\Entity
I have 2 bundles with entities and several connections into doctrine config
orm:
default_entity_manager: site
entity_managers:
site:
connection: siteConfig
mappings:
CSSBundle: ~
forum:
connection: forumConfig
mappings:
IPBBridgeBundle: ~
and this into provider
providers:
main:
entity: { class: Telnet\IPBBridgeBundle\Entity\Member, property: username }
What I'm doing wrong?
SecurityBundle use default Entity Manager, and Entity, that implements UserInterface must be handled by default Entity Manager.
Related
I have 2 entity managers, each for one of my databases DATABASE_URL and DATABASE_URL_SAGE:
# config/packages/doctrine.yaml
doctrine:
dbal:
default_connection: site
connections:
site:
url: '%env(resolve:DATABASE_URL)%'
driver: 'pdo_sqlsrv'
# ...
sage:
url: '%env(resolve:DATABASE_URL_SAGE)%'
driver: 'pdo_sqlsrv'
# ...
orm:
auto_generate_proxy_classes: true
default_entity_manager: site
entity_managers:
site:
connection: site
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
mappings:
Site:
is_bundle: false
type: attribute
dir: '%kernel.project_dir%/src/Entity/Site'
prefix: 'App\Entity\Site'
alias: Site
sage:
connection: sage
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
mappings:
Sage:
is_bundle: false
type: attribute
dir: '%kernel.project_dir%/src/Entity/Sage'
prefix: 'App\Entity\Sage'
alias: Sage
I would like to create an entity which:
has a ManyToOne relation with another entity managed by the same entity manager (site)
has another ManyToOne relation with another entity managed by the sage entity manager
Something like this:
// src/Entity/Site/CategoryFArticle.php
namespace App\Entity\Site;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class CategoryFArticle
{
#[ORM\ManyToOne(targetEntity: 'App\Entity\Site\Category')]
private $category;
#[ORM\ManyToOne(targetEntity: 'App\Entity\Sage\FArticle')]
private $fArticle;
}
The problem is when I do that I got the error:
Mapping
-------
[FAIL] The entity-class App\Entity\Site\CategoryFArticle mapping is invalid:
* The target entity 'App\Entity\Sage\FArticle' specified on App\Entity\Site\CategoryFArticle#fArticle is unknown or not an entity.
Database
--------
In MappingException.php line 23:
The class 'App\Entity\Sage\FArticle' was not found in the chain configured namespaces App\Entity\Site
Questions
Is doctrine able to manage this kind of mapping (with entities managed by differents entity managers) ?
If so, how can I configure my current code to work ?
Thank you
I am working on upgrade Symfony 3.3 to 4.4 and almost done with it, but I have one last issue.
I enabled autowiring with default config, but whole project uses lots of #ParamConverter conversions without annotation.
Problem: ParamConverter with auto_convert tries to convert services and classes that are mentioned to controller by typehinting for autowiring (not entities).
Controller:
/**
* #Route("/report", name="report_page")
*/
public function report(
Request $request,
FileManager $fileManager
): Response {
// code
}
Error:
The class 'App\Service\FileManager' was not found in the chain configured namespaces App\Entity.
Service 'App\Service\FileManager' exists and works correctly.
ParamConverter config (by default 'request: {converters: true, auto_convert: true}'):
sensio_framework_extra:
router:
annotations: false
Doctrine config:
doctrine:
dbal:
default_connection: default
connections:
default:
# config
orm:
auto_generate_proxy_classes: '%kernel.debug%'
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
mappings:
Base:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: App\Entity
Controller setting (services.yaml):
services:
_defaults:
autowire: true
autoconfigure: true
public: false
App\:
resource: '../src/*'
exclude: '../src/{DataFixtures,Entity,Objects,Repository,Utils}'
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
I understand that I can set 'sensio_framework_extra.request.auto_convert' to false and use #ParamConverter annotation everywhere in controllers, but there are too many places with this conversion and I try to get default behavior, so additional #ParamConverter annotations would be extra.
Just in case: I tried to disable auto_convert and everything worked correctly (services were autowired and entities were passed to controllers).
Also I checked that I installed last available versions of packages and bundles.
Need some hints on it. Probably I missed something. I tried to find exact way how ParamConverter works by default and how it checks that class is entity or not, but it is too complicated and I decided that I dug too deep.
EDIT:
Probably I have some issue with autowiring's config and not paramconverter. But I checked php bin/console debug:autowiring and got all needed services as available via autowiring.
It looks like symfony is trying to convert the fileManager like an entity.
Try moving the injected service(s) into the __construct method of the controller (and add the property to the controller) like:
private $fileManager;
...
public function __construct(FileManager $fileManager) {
$this->fileManager = $fileManager;
}
and then access it in the report method:
$this->fileManager
I have configured two connections to the database. One connection is called user and other is called client. This is the configuration in the config.yml file:
doctrine:
dbal:
default_connection: client
connections:
client:
driver: pdo_mysql
host: '%client_database_host%'
port: '%client_database_port%'
dbname: '%client_database_name%'
user: '%client_database_user%'
password: '%client_database_password%'
charset: UTF8
mapping_types:
enum: string
user:
driver: pdo_mysql
host: '%user_database_host%'
port: '%user_database_port%'
dbname: '%user_database_name%'
user: '%user_database_user%'
password: '%user_database_password%'
charset: UTF8
mapping_types:
enum: string
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: ~
entity_managers:
client:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
ProjectModelBundle: ~
connection: client
user:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
BaseModelBundle: ~
ProjectModelBundle: ~
connection: user
But I am always getting the first entity manager no matter what. This is how I am using entity manager's in services:
# BASE
htec.project_model_bundle.repository.database.client_base:
class: Project\BaseModelBundle\Repository\Database\DatabaseRepository
arguments: ['#service_container', '#doctrine.orm.client_entity_manager', '#form.factory']
htec.project_model_bundle.repository.database.user_base:
class: Project\BaseModelBundle\Repository\Database\DatabaseRepository
arguments: ['#service_container', '#doctrine.orm.user_entity_manager', '#form.factory']
But no matter what I do, I always get the first entity manager that I have defined under orm->entity_managers settings. For example if configure orm like this:
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: ~
entity_managers:
client:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
ProjectModelBundle: ~
connection: client
user:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
BaseModelBundle: ~
ProjectModelBundle: ~
connection: user
I will always get the client entity manager even if I supply '#doctrine.orm.user_entity_manager' as service argument.
If I configure orm like this:
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: ~
entity_managers:
user:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
BaseModelBundle: ~
ProjectModelBundle: ~
connection: user
client:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
ProjectModelBundle: ~
connection: client
I will always get the user entity manager even if I supply '#doctrine.orm.client_entity_manager' as service argument.
What am I doing wrong here?
Recently I had a similar issue. The comment of #dbrumann gave me a good clue for resolve it. I used the next approach:
If you use the console command debug:autowiring you will see there is a service aliased as doctrine.
Doctrine\Common\Persistence\ManagerRegistry alias to doctrine
You can get access to that service in your target class by type-hinting, put the name of the service class (or interface) as argument in the constructor of your target class.
Now you can access all the methods of the service in your target class, by using the method getManager() you will get any of your managers:
use Doctrine\Common\Persistence\ManagerRegistry;
$protected $managerRegistry;
public function __construct(ManagerRegistry $managerRegistry)
{
$this->managerRegistry = $managerRegistry;
}
public function foo()
{
// asuming your managers names are default and second
$firstManager = $this->managerRegistry->getManager('default');
$secondManager = $this->managerRegistry->getManager('second');
}
So you defined a service named DatabaseRepository that exists in two variations. At one point it receives the 'client' entity manager, and at another point it receives 'user' entity manager?
I think it always returns you the 'client' manager most probably because that is the first time the service has been defined for the service container. It does not matter what you define it afterwards in the same .yml code.
Now, there is a big "why" rhetoric question for you. Why didn't you define two service classes, each for particular manager? If you really had to do it that way, that indicates some serious design problems in the remaining code of your Project.
Another suggestion: Do name your classes somewhat more descriptive. An entity manager and repository class certainly do something about a database. Naming classes, properties, variables in a proper way I find to be one of the most challenging part of the work, but it makes our lives easier.
Btw. Avoid passing entire container as service parameter:
arguments: ['#service_container',
because it's too expensive resources wise.
I have my model entities saved in src/AppBundle/Model/Entity.
You can understand, that i have own custom folder for entities (in model folder).
This is my orm settings in config.yml:
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: false
mappings:
user:
type: annotation
dir: %kernel.root_dir%/../src/AppBundle/Model/Entity
alias: 'Entity'
prefix: AppBundle\Model\Entity
is_bundle: false
I have a problem with these lines in my security.yml:
providers:
our_db_provider:
entity:
class: AppBundle:User
property: username
# if you're using multiple entity managers
# manager_name: customer
There is some error:
Unknown Entity namespace alias 'AppBundle'.
I don't what ref I have to use (AppBundle:User probably not).
Thank you for your answers.
By default, all Symfony bundles will have a nice alias: XxxBundle (aliasing the NamespaceOfXxxBundle\Entity namespace). As you're bundle doesn't follow this convention and stores it in Model\Entity instead, you have 2 options:
Don't use the alias feature and pass the FQCN: AppBundle\Model\Entity\User
Create a new alias, give it a nice name and use it:
doctrine:
orm:
# ...
mappings:
user:
type: annotation
dir: %kernel.root_dir%/../src/AppBundle/Model/Entity
alias: App # <-- the alias name
prefix: AppBundle\Model\Entity
is_bundle: false
App:User
i have read the documentation of symfony2 in relation to the performance and I have realized the following steps.
Install APC 'php-apc' on my webserver and restart my webserver
Modify my doctrine configuration
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
metadata_cache_driver: apc
result_cache_driver: apc
query_cache_driver: apc
Now if i call a action to retrieve all users from database i see in the information bar at the bottom that doctrine execute every time 114 queries. Why the queries not cached?
My action look like this:
$users = $this->getDoctrine()->getRepository('AppUserBundle:User')->findAll();
return $this->render('AppUserBundle:User:index.html.twig', array('users' => $users));
Doctrine doesn't cache query results by default. You have to explicitly point that you want to cache query using useResultCache method. For example, if you'd like to cache getting all users, write your own method in User repository class:
use Doctrine\ORM\EntityRepository;
class UserRepository extends EntityRepository
{
public function fetchAll()
{
$query = $this->createQueryBuilder('u')->getQuery();
return $query->useResultCache(true)->getResult();
}
}
The method may take additional arguments:
public function useResultCache($bool, $lifetime = null, $resultCacheId = null)
$bool - set to true if you want to cache query result
$lifetime - TTL of cached result in seconds
$resultCacheId - you can pass your own id, in case of null Doctrine will handle that