Using Symfony-2.1 and Doctrine-2.3. I have multiple databases and need to do cross-database joins so I followed the suggestions in:
Multiple database connection in Doctrine2 and Zend framework
Using Relationships with Multiple Entity Managers
and set up multiple connections and one entity manager. Here is app/config/config.yml:
doctrine:
dbal:
default_connection: db1
connections:
db1:
driver: pdo_mysql
host: 127.0.0.1
dbname: db1
db2:
driver: pdo_mysql
host: 127.0.0.1
dbname: db2
orm:
default_entity_manager: default
auto_generate_proxy_classes: %kernel.debug%
entity_managers:
default:
auto_mapping: true
mappings:
FirstBundle:
type: annotation
dir: Model
prefix: NoiseLabs\FirstBundle\Model
SecondBundle:
type: annotation
dir: Model
prefix: NoiseLabs\SecondBundle\Model
Entity class in FirstBundle:
namespace NoiseLabs\FirstBundle\Model;
/**
* #ORM\Entity
* #ORM\Table(name="db1.table1")
*/
class FirstEntity
{
/**
* #ORM\Id
* #ORM\Column(name="id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
}
Entity class in SecondBundle:
namespace NoiseLabs\SecondBundle\Model;
/**
* #ORM\Entity
* #ORM\Table(name="db2.table2")
*/
class SecondEntity
{
/**
* #ORM\Id
* #ORM\Column(name="id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="NoiseLabs\FirstBundle\Model\FirstEntity")
* #ORM\JoinColumn(name="firstId", referencedColumnName="id", onDelete="CASCADE")
*/
protected $first;
}
Now, the problem is app/console doctrine:schema:update --dump-sql only detects schema changes in (default connection) db1.tables. If I set the default connection to db2 it will only output sql related to db2.tables.
I've checked with app/console doctrine:mapping:info and all entity classes are being mapped.
Is this a limitation of Doctrine/Symfony or do I need to adjust my configuration? Thanks.
Each entity manager can have only one connection. Split the default entity manager into two. app/console doctrine:schema:update takes an optional argument (em) to specify the entity manager in use. You'd have to run it twice:
app/console doctrine:schema:update --dump-sql em="default"
app/console doctrine:schema:update --dump-sql em="my_second_em"
There's also a short article (How to work with Multiple Entity Managers and Connections) in the Symfony2 cookbook that's worth reading.
Related
I learn Symfony2 and i have a problem with database. I use this documentation: http://symfony.com/doc/2.7/book/doctrine.html
I have Product.php class, but when i try execute this command:
php app/console doctrine:generate:entities AppBundle/Entity/Product
i get error:
"Class "AppBundle\Entity\Product" is not a valid entity or mapped super class."
This is my Product.php file:
<?php
/**
* Created by PhpStorm.
* User: Marcin
* Date: 20.12.2015
* Time: 23:33
*/
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="product")
*/
class Product
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=100)
*/
protected $name;
/**
* #ORM\Column(type="decimal", scale=2)
*/
protected $price;
/**
* #ORM\Column(type="text")
*/
protected $description;
}
Other people have the same error, but they don't have "#ORM\Entity" in their code. I have, but problem still existing.
I have no idea what's going on...
Update:
This is fragment of config.yml:
doctrine:
dbal:
driver: pdo_mysql
host: localhost
port: 3306
dbname: db_name
user: db_user
password: db_password
charset: UTF8
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: "%kernel.root_dir%/data/data.db3"
# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
# path: "%database_path%"
orm:
auto_generate_proxy_classes: "%kernel.debug%"
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
Updated2:
I changed config.yml:
orm:
auto_generate_proxy_classes: "%kernel.debug%"
# naming_strategy: doctrine.orm.naming_strategy.underscore
# auto_mapping: true
entity_managers:
default:
mappings:
AppBundle: ~
And when i use:
php app/console doctrine:mapping:info
I get:
"You do not have any mapped Doctrine ORM entities according to the current configuration. If you have entities or mapping files you should check your mapping configuration for errors."
I'm following this Symfony2/Doctrine guide and I've come to the part where I need to create getters/setters. but I am stuck with this part:
$ php app/console doctrine:generate:entities Acme/StoreBundle/Entity/Job
I've searched the net for possible solutions (seems to mainly revolve around using 2 asterisks for the start) but couldn't find the solution.
Some info:
Bundle is properly loaded (via AppKernel.php) as I have a test "hello world" and that works.
The namespace path is correct
Job.php exists in the right folder
I'm using postgres as my database. I'm not sure if this matters.
I have tried with and without the use Doctrine\ORM\Mapping line in model class (see below for code)
I don't think I'm running a accelerator at least according to get_loaded_extensions function
Any ideas would be very helpful.
Thanks a lot :)
snippet of my settings.yml
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
# if using pdo_sqlite as your database driver, add the path in parameters.yml
# e.g. database_path: "%kernel.root_dir%/data/data.db3"
# path: "%database_path%"
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
Model class
<?php
// src/MyApp/MyBundle/Model/Job.php
namespace MyApp\MyBundle\Model;
use Doctrine\ORM\Mapping as ORM;
/**
* MyApp\MyBundle\Model\Job
*
* #ORM\Entity
* #ORM\Table(name="myschema.jobs")
*/
class Job {
/**
* #ORM\Column(name="job_id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $jobid;
/**
* #ORM\Column(name="name", type="text")
*/
protected $name;
/**
* #ORM\Column(name="job_desc", type="text")
*/
protected $description;
/**
* #ORM\Column(name="personal_req", type="text")
*/
protected $requirements;
}
did you create your entity using doctrine? I saw on your Job.php entity you are using annotation as mapping format.
In error output it said doctrine can't find any mapped entities. I've been there and it solved with specific configuration of your config.yml.
Try to change this on your config.yml
doctrine:
dbal:
driver: "%database_driver%"
#etc
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: false
mappings:
MyAppMyBundle:
type: annotation #On your case it should be annotation
dir: Resources/Model/
Read this maybe it can help:
Doctrine Mapping in Symfony2 using YAML
Have you tried using following console command ?
$ php app/console doctrine:generate:entities MyApp/MyBundle/Model
I hope it will work. Your entity namespace is different than Acme/StoreBundle/Entity/Product. Your entities are in Model directory/namespace so you should use first argument of command a valid namespace. So that following cmd generates error as you have mentioned above.
$ php app/console doctrine:generate:entities Acme/StoreBundle/Entity/Product
I am generating an Entity from php Class:
<?php
// src/Printing/Productesbundle/Entity/User.php
namespace Printing\ProductesBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="UsersStamp")
*/
class UserStamp
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue
*/
private $id;
}
?>
When I execute
php app/console doctrine:generate:entities Printing/ProductesBundle/Entity/UserStamp
it returns me the following error
[Doctrine\ORM\Mapping\MappingException]
Class "Printing\ProductesBundle\Entity\UserStamp" is not a valid entity or mapped super class.
What am i missing??
Thank you!
PS:
That's my Doctrine Configuration:
# Doctrine Configuration
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
# if using pdo_sqlite as your database driver, add the path in parameters.yml
# e.g. database_path: "%kernel.root_dir%/data/data.db3"
# path: "%database_path%"
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
Could you try command below?
app/console doctrine:generate:entities PrintingProductesBundle:UserStamp
I think you need to execute something like this
php app/console doctrine:generate:entities ProductesBundle
After trying some tricks I found the solution.
I guess the error radicates on the fact that I have entities generated previously from database.
To solve this question, you have to remove the content of the config/doctrine folder.
Thanks to #Javad to keep trying!
I have two bundles both under Site.. Any Entity i create in User is processed but any entity that is added to Core is skipped.. I moved all the Entities from User to Core and created a text Entity but know im getting an error:
No Metadata Classes to process.
The test class looks like this:
<?php
namespace Site\CoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Test
*
* #ORM\Table(name="user_address_type")
* #ORM\Entity
*/
class Test
{
/**
* #var integer
*
* #ORM\Column(name="Test", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $addressTypeId;
/**
* #var string
*
* #ORM\Column(name="address_description", type="string", length=100, nullable=true)
*/
private $address_description;
}
My config is this:
# Doctrine Configuration
doctrine:
dbal:
default_connection: default
connections:
default:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
# if using pdo_sqlite as your database driver, add the path in parameters.yml
# e.g. database_path: "%kernel.root_dir%/data/data.db3"
# path: "%database_path%"
orm:
default_entity_manager: default
entity_managers:
default:
connection: default
mappings:
SiteCoreBundle: ~
SiteUserBundle: ~
I have searched all over the place with no answer to be found. The closet was about using multiple connections which is where the config came from.
Thanks..
In an attempt to define a one-to-many relationship across bundles the following occurs:
The class 'Mana\ClientBundle\Entity\Member' was not found in the chain
configured namespaces Mana\SplitBundle\Entity
Update 3:
I've now seen conflicting answers that the relationship can and cannot be accomplished. On the assumption that it can (because others here at stackoverflow seem to have done it), what configuration is required other than registering the bundles in AppKernel.php and entering the annotations in the entities? The resolve_target_entity_listener did not appear to make a difference.
Update 2:
Well, I know I'm way out of my depth here, but this is what I observed while stepping through the code when trying to show a Client entity.
The error message in the profiler
The target entity 'Mana\ClientBundle\Entity\Member' specified on
Mana\SplitBundle\Entity\Client#members is unknown or not an entity.
occurs because SchemaValidator evaluates $cmf->isTransient($assoc['targetEntity']) to true, where the targetEntity in the Member entity. The PHPdoc comment suggests that this entity's metadata is not loaded. If I understand this correctly, that means that the annotation regarding the relationship is not loaded. But observing variable values suggests that the annotations have been read.
Am I totally missing something that should be painfully obvious? Or am I too far out in left field?
Update 1:
I have confirmed that doctrine:mapping:info will detect improper FQCN. The data fixtures are correct. Use of entity managers and database-connection for both default and split connections are correct. The error persists and can occur for any of the relationships defined in the Client entity, either OneToMany or ManyToOne.
config.yml:
doctrine:
dbal:
default_connection: default
connections:
default:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
mapping_types:
enum: string
split:
driver: "%database_driver2%"
host: "%database_host2%"
port: "%database_port2%"
dbname: "%database_name2%"
user: "%database_user2%"
password: "%database_password2%"
charset: UTF8
mapping_types:
enum: string
entity_managers:
default:
connection: default
mappings:
ManaClientBundle: ~
split:
connection: split
mappings:
ManaSplitBundle: ~
Client entity:
/**
* #ORM\OneToMany(targetEntity="Mana\ClientBundle\Entity\Member", mappedBy="client")
* #ORM\OrderBy({"dob" = "ASC"})
*/
protected $members;
Member entity:
/**
* #ORM\ManyToOne(targetEntity="Mana\SplitBundle\Entity\Client",inversedBy="members",cascade={"remove", "persist"})
* #ORM\JoinColumn(name="cid", referencedColumnName="id")
*
*/
protected $client;
Doctrine mapping:
$ php app/console doctrine:mapping:info
Found 12 mapped entities:
[OK] Mana\ClientBundle\Entity\Agency
[OK] Mana\ClientBundle\Entity\Center
[OK] Mana\ClientBundle\Entity\Contact
[OK] Mana\ClientBundle\Entity\Contactdesc
[OK] Mana\ClientBundle\Entity\Counties
[OK] Mana\ClientBundle\Entity\Ethnicity
[OK] Mana\ClientBundle\Entity\Incomehistory
[OK] Mana\ClientBundle\Entity\Incomesrc
[OK] Mana\ClientBundle\Entity\Member
[OK] Mana\ClientBundle\Entity\Note
[OK] Mana\ClientBundle\Entity\Referral
[OK] Mana\ClientBundle\Entity\User
$ php app/console doctrine:mapping:info --em=split
Found 1 mapped entities:
[OK] Mana\SplitBundle\Entity\Client
You should see Using Relationships with Multiple Entity Managers
A cross-bundle relationship cannot be managed by Doctrine if you have separate databases with separate connections and entity managers. Instead, in this case, the Client entity would have to reside in the same schema/bundle and be periodically refreshed from the external source.
But if you have only one connection to the database and one entity manager for it you can manage cross-bundle relationships. (Described here: OneToMany Relation on cross project entities (Symfony2/Doctrine))