Symfony2 Relation between entities cross Bundles and multiple entity manager - symfony

I'm using Symfony 2.7. I followed documentation on Symfony2 about How to Work with multiple Entity Managers and Connections. I tried every solutions on this site but without success. I have always the same error :
[Doctrine\Common\Persistence\Mapping\MappingException] The class
'Spot\OfferBundle\Entity\Offer' was not found in the chain configured
namespaces Dashboard\ProjectBundle\Entity
In my project, I have 2 bundles. Every bundle works with a different entity manager. Here my config file :
# Doctrine Configuration
doctrine:
dbal:
default_connection: default
connections:
default:
driver: %database2_driver%
host: %database2_host%
port: %database2_port%
dbname: %database2_name%
user: %database2_user%
password: %database2_password%
charset: UTF8
spot:
driver: %database3_driver%
host: %database3_host%
port: %database3_port%
dbname: %database3_name%
user: %database3_user%
password: %database3_password%
charset: UTF8
orm:
auto_generate_proxy_classes: %kernel.debug%
default_entity_manager: default
entity_managers:
default:
connection: default
mappings:
DashboardProjectBundle: ~
spot:
connection: spot
mappings:
SpotOfferBundle: ~
I have two entities with relations across bundles
The first :
namespace Dashboard\ProjectBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Project
*
* #ORM\Table(name="project")
* #ORM\Entity
*/
class Project
{
/**
* #var Spot\OfferBundle\Entity\Offer
*
* #ORM\ManyToOne(targetEntity="Spot\OfferBundle\Entity\Offer", inversedBy="projects")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="offer_id", referencedColumnName="id")
* })
*/
private $offer;
And the second :
namespace Spot\OfferBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Offer
*
* #ORM\Table(name="offer")
* #ORM\Entity(repositoryClass="Spot\OfferBundle\Entity\OfferRepository")
*/
class Offer {
/**
*
* #ORM\OneToMany(targetEntity="Dashboard\ProjectBundle\Entity\Project", mappedBy="offer")
*/
private $projects;
I try with use statement, I check AppKernel and Bundles are defined. I try with leading backslashes. But nothig works.

Make sure that you have set this in the config file:
assetic:
...
bundles: [ DashboardProjectBundle, SportOfferBundle]
UPDATE:
Also, try to set orm config like this:
orm:
auto_generate_proxy_classes: %kernel.debug%
default_entity_manager: default
entity_managers:
default:
connection: default
mappings:
DashboardProjectBundle: ~
SpotOfferBundle: ~
spot:
connection: spot
mappings:
SpotOfferBundle: ~

Related

Multiple entity manager: The target entity specified on is unknown or not an entity

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

Symfony 3 - "Class was not found in the chain configured namespaces" when trying to build a relationship between two entities of two bundles

Using Symfony 3.4.2 , I am trying to build a relationship between two entities of two different bundles which uses their own databases located on different servers.
In other words, we have two databases, and then two entities managers :
One existing MariaDB database [person] which store one "person" table, used by many other applications.
One new MariaDB database [app] dedicated for the application.
Note that I can't change anything on that situation (legacy applications must still running). Althought it is planned "in the future" to replace the [person] database by a REST Api.
Following the Symfony doc (https://symfony.com/doc/3.4/doctrine/multiple_entity_managers.html), this gives the following app/config/config.yml file :
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: en
framework:
#esi: ~
#translator: { fallbacks: ['%locale%'] }
secret: '%secret%'
router:
resource: '%kernel.project_dir%/app/config/routing.yml'
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
#serializer: { enable_annotations: true }
default_locale: '%locale%'
trusted_hosts: ~
session:
# https://symfony.com/doc/current/reference/configuration/framework.html#handler-id
handler_id: session.handler.native_file
save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'
fragments: ~
http_method_override: true
assets: ~
php_errors:
log: true
# Twig Configuration
twig:
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
# Doctrine Configuration
doctrine:
dbal:
default_connection: default
connections:
default:
driver: pdo_mysql
host: '%database_host%'
port: '%database_port%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
# charset: UTF8
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: '%kernel.project_dir%/var/data/data.sqlite'
# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
#path: '%database_path%'
acme_another_db :
driver: pdo_mysql
host: '%acme_another_database_host%'
port: '%acme_another_database_port%'
dbname: '%acme_another_database_name%'
user: '%acme_another_database_user%'
password: '%acme_another_database_password%'
# charset: UTF8
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: '%kernel.project_dir%/var/data/data.sqlite'
# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
#path: '%database_path%'
orm:
# Let's disable auto_mapping since we have several entity_managers
# auto_mapping: true
default_entity_manager: default
entity_managers:
default:
naming_strategy: doctrine.orm.naming_strategy.underscore
connection: default
mappings:
AppBundle: ~
acme_another_em:
naming_strategy: doctrine.orm.naming_strategy.underscore
connection: acme_another_db
mappings:
AcmeAnotherBundle: ~
auto_generate_proxy_classes: '%kernel.debug%'
# Swiftmailer Configuration
swiftmailer:
transport: '%mailer_transport%'
host: '%mailer_host%'
username: '%mailer_user%'
password: '%mailer_password%'
spool: { type: memory }
Since the "person" table is to be used by many other applications, I choosed to create a separate bundle.
In terms of entity, I have then 3 entities :
Acme/AnotherBundle/Entity/Person
AppBundle/Entity/Book
AppBundle/Entity/BookInterest
The first entity was generated without any error.
The AppBundle/Entity/Book and AppBundle/Entity/BookInterest entities were generated via bin\console generate:doctrine:entity without any problem.
Before updating the database schema, I added the relationship in the AppBundle/Entity/BookInterest entity class file (relation to Acme/AnotherBundle/Entity/Person and to AppBundle/Entity/Book), following the Symfony doc (http://symfony.com/doc/3.4/doctrine/associations.html).
/**
* #ORM\ManyToOne(targetEntity="Book", inversedBy="book")
* #ORM\JoinColumn(name="fk_book_id", referencedColumnName="id", nullable=false)
*/
private $book;
/**
* #ORM\ManyToOne(targetEntity="Acme\AnotherBundle\Entity\Person")
* #ORM\JoinColumn(name="fk_person_id", nullable=false)
*/
private $person;
But, when I try to update the schema via bin\console doctrine:schema:update --force --em=default, I have the following error message :
In MappingException.php line 37: The class
'Acme\AnotherBundle\Entity\Person' was not found in the chain
configured namespaces AppBundle\Entity
Adding "use Acme\AnotherBundle\Entity\Person;" in the top of \src\AppBundle\Entity\BookInterest.php and clearing the cache via bin\console cache:clear does not solve the problem.
Did I miss something in the app/config/config.yml configuration file, or in the \src\AppBundle\Entity\BookInterest.php entity class file ?
Doctrine2 unable to handle one relationship between two entity managers ?
I also found a (quite old) post on a similar problem (Using Relationships with Multiple Entity Managers), which indicates that Doctrine2 is unable to do that (due to the use of two entity managers).
If this is still the case, what is the best way to handle that situation ?
Is using one simple integer field without relation in the AppBundle/Entity/BookInterest for storing person_id and create manuals validation checks (then manual queries) in the BookInterestController is a good practice ?
Thanks a lot in advance for any tips (and good practice advices) to solve that case ! :-)

Symfony 3 / Multiple Doctrine EM within Bundle

I have been following this tutorial https://symfony.com/doc/3.3/doctrine/multiple_entity_managers.html (but it's more for different connections/em on different Bundles) and then a few more links around the web to try and get different Entities in different databases WITHIN THE SAME BUNDLE, that interract together, I tried everything but nothing seem to be working...
At first I thought that the fact that all my entities are in the ModelBundle/Entity/ folder was the problem, so I actually moved all my default Entities in /ModelBundle/EntityInternal/ and the other entities I want to move to another database in the /ModelBundle/EntityRest/
(At the moment I'm just trying to make it work with 2 separate mysql databases, but the idea after that is to use the CircleOfNice/DoctrineRestDriver for the secondary EM)
This is my current config :
doctrine:
dbal:
default_connection: default
connections:
default:
driver: pdo_mysql
host: '%database_host%'
port: '%database_port%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
server_version: '5.6'
secondary:
driver: pdo_mysql
host: '%database_host2%'
port: '%database_port2%'
dbname: '%database_name2%'
user: '%database_user2%'
password: '%database_password2%'
charset: UTF8
server_version: '5.6'
orm:
#auto_generate_proxy_classes: '%kernel.debug%'
#naming_strategy: doctrine.orm.naming_strategy.underscore
#auto_mapping: true
default_entity_manager: default
entity_managers:
default:
connection: default
mappings:
ModelBundle:
type: "annotation"
dir: "EntityInternal"
prefix: "ModelBundle\\EntityInternal"
secondary:
connection: secondary
mappings:
ModelBundle:
type: "annotation"
dir: "EntityRest"
prefix: "ModelBundle\\EntityRest"
The first Entity I tried to move in the secondary connection/EM :
namespace ModelBundle\EntityRest;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
use ModelBundle\Model\ModelTrait\SeoTrait;
use ModelBundle\Model\ModelTrait\NameTrait;
/**
* ModelBundle\EntityRest\Level2
*
* #ORM\Table(name="level2")
* #ORM\Entity(repositoryClass="ModelBundle\Repository\LevelRepository")
*/
class Level2
{
use SeoTrait;
use NameTrait;
/**
* #var integer
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToMany(targetEntity="\ModelBundle\EntityInternal\Offer", mappedBy="levels2")
* #ORM\JoinColumn(name="offer_id", referencedColumnName="id", nullable=true)
*/
private $offers;
/**
* #ORM\ManyToMany(targetEntity="\ModelBundle\EntityInternal\User", mappedBy="levels2")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true)
*/
private $users;
and the linked entity that remains in the default EM/Connection
/**
* ModelBundle\EntityInternal\Offer
*
* #ORM\Table(name="offer")
* #ORM\Entity(repositoryClass="ModelBundle\Repository\OfferRepository")
* #ORM\HasLifecycleCallbacks
*/
class Offer
{
use SeoTrait;
use DateTrait;
use ValidTrait;
use PremiumTrait;
use NameTrait;
/**
* #var integer
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
(....)
/**
* #ORM\ManyToMany(targetEntity="Level", inversedBy="offers")
* #ORM\JoinColumn(nullable=false)
*/
private $levels;
/**
* #ORM\ManyToMany(targetEntity="\ModelBundle\EntityRest\Level2", inversedBy="offers")
* #ORM\JoinColumn(nullable=false)
*/
private $levels2;
The doctrine:mapping:info outputs the right entities :
$ bin/console doctrine:mapping:info --em secondary
Found 1 mapped entities:
[OK] ModelBundle\EntityRest\Level2
$ bin/console doctrine:mapping:info
Found 17 mapped entities:
[OK] ModelBundle\EntityInternal\Domain
[OK] ModelBundle\EntityInternal\Application
[OK] ModelBundle\EntityInternal\Region
[OK] ModelBundle\EntityInternal\Offer
[OK] ModelBundle\EntityInternal\Diploma
[OK] ModelBundle\EntityInternal\ArticleCategory
[OK] ModelBundle\EntityInternal\City
[OK] ModelBundle\EntityInternal\County
[OK] ModelBundle\EntityInternal\User
[OK] ModelBundle\EntityInternal\Sector
[OK] ModelBundle\EntityInternal\Level
[OK] ModelBundle\EntityInternal\Company
[OK] ModelBundle\EntityInternal\SectorGroup
[OK] ModelBundle\EntityInternal\DomainGroup
[OK] ModelBundle\EntityInternal\Media
[OK] ModelBundle\EntityInternal\Article
[OK] ModelBundle\EntityInternal\Contract
But the schema:update just doesn't want to work
$ bin/console doctrine:schema:update --em secondary
[Doctrine\Common\Persistence\Mapping\MappingException]
The class 'ModelBundle\EntityInternal\Offer' was not found in the chain configured namespaces ModelBundle\EntityRest
$ bin/console doctrine:schema:update
[Doctrine\Common\Persistence\Mapping\MappingException]
The class 'ModelBundle\EntityRest\Level2' was not found in the chain configured namespaces ModelBundle\EntityInternal
I've been trying about everything for a few days now and that's always the error I fall back to... Do I have to move these entities in another bundle ? Is it just impossible for doctrine to link entities from different namespaces or connections ?

Doctrine schema:update generates the same SQL again and again

Running bin/console doctrine:schema:update --force again and again, it always output 39 queries executed even after clearing cache/restarting php-fpm. So it always execute the same SQL requests again and again...
The SQL looks likes (from --dump-sql)
ALTER TABLE apply_queue CHANGE cv_id cv_id INT DEFAULT NULL, CHANGE team_id team_id INT DEFAULT NULL;
....
And a lot of lines similar to this.
The ApplyQueue class look like:
/**
* AppBundle\Entity\ApplyQueue.
*
* #ORM\Entity(repositoryClass="AppBundle\Entity\ApplyQueueRepository")
* #ORM\Table(name="apply_queue")
*/
class ApplyQueue
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Cv")
* #ORM\JoinColumn(name="cv_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $cv;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Team")
* #ORM\JoinColumn(name="team_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $team;
...
}
DBAL config :
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
types:
json: Sonata\Doctrine\Types\JsonType
review_status: AppBundle\Model\Enum\ReviewStatusEnumType
mapping_types:
review_status: string
The structure of the table:
This is an "old" project that has been upgraded to Symfony 3.4 and MariaDB 10.2.
Thanks
MariaDB 10.2 is not yet supported by Doctrine, causing this problem.
See linked PR : https://github.com/doctrine/dbal/pull/2825
I had similar problem few weeks ago. In my case it was that after update
--force
it shows some column must be set not null on
--dump-sql.
Again and again. I don't remember so good what was problem but it was something like this:
I had for same column set to be null and to have default value. Without doctrine that could even work somehow, but doctrine expects tables to be designed good.
What I want to say check your table. There is probably some error of this type. Goodluck!
check your database table type - i had a problem where the database type didnt support the feature doctrine trying to set.
Maybe run the sql on the database server and see if it 'works' / changes anything, then re-run
In your app/config/config.yml, check if doctrine cache is enabled as below :
doctrine:
orm:
metadata_cache_driver: redis
If so, you will have to flush redis cache:
php bin/console redis:flushdb --client=CLIENT_NAME -n

Symfony2 - Class X is not a valid entity or mapped super class

After working for several months, suddenly I'm getting this error when I try and run a command from the terminal. The "X" is a User entity, extending the FOSUserBundle.
Looking at some of the similar questions on here, the common errors seem to be incorrect annotations, not registering the bundle in the AppKernel, or not having auto_mapping enabled in the config.
The user class starts (I don't think the properties are necessary?) like this:
<?php
namespace Acme\UserBundle\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table()
*/
class User extends BaseUser
{
// ...
}
The bundle is registered in the AppKernel:
$bundles = array(
// ...
new Acme\UserBundle\UserBundle(),
// ...
);
Auto mapping is enabled (and not disabled in either the _prod or _dev configs) as you can see here:
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
Plus the FOSUserBundle is being told the correct entity to use:
fos_user:
db_driver: orm
firewall_name: main
user_class: Acme\UserBundle\Entity\User
Doesn't work?
I stumbled upon one question on here where it was solved by disabling eAccelerator. We do have eAccelerator running on the server, but after clearing the cache I've verified the local value in the phpinfo() output is disabled when running the command, as was already expected:
eaccelerator.enable => 0 => 1
eaccelerator.optimizer => 0 => 1
When I run the doctrine:mapping:info command I can see that my UserBundle is missing. I'm at a complete loss here as to what is missing or incorrect. Does anybody have any suggestions? It's worth mentioning that the front-end of the website works fine, which makes use of the User entity.
I got this issue and it was a sleepy mistake to remove the EntityRepository with the whole #Entity line, causing the "not a valid entity" error.
I spent a lot searching for the issue with the FOSUserBundle:User superclass map but the problem was on my class, I had to know that when it didnt appear on doctrine:mapping:info.

Resources