Entities associations across different managers - symfony

I have a small question about doctrine and Symfony 2:
Is it possible to declare a relation (OneToMany) between two entities which are managed by two different entity managers (and two different DB connections) ?
To be more precise, I have two bundles :
FpnABundle -> Mapped with A_database (and A_entitymanager)
FpnBBundle -> Mapped with B_database (and B_entitymanager)
And I need to define an association between FpnABundle:User and FpnBBundle:Post
If I try to do that, when I perform a DB schema update, I have the following error :
The class 'Fpn\ABundle\Entity\User' was not found in the chain configured namespaces Fpn\BBundle\Entity
Thanks for your help!

Basically, the answer is no.
You will probably need to do this: http://symfony.com/doc/current/cookbook/doctrine/resolve_target_entity.html
Even with this it will only work if the two databases are on the same server. And at some point you will probably need to add the schema name to the the table name. Somewhat painful.

Related

Symfony2 - extending existing non-abstract entity?

Let's say I have a Setting entity with some fields like IntValue, dateValue, stringValue and some linked entities, like countries (ManyToMany to entity Country), languages (ManyToMany to Language) etc.
Settings are created by users and assigned to specific objects (not important here, but I wanted to clarify).
Now I suddenly need to have UserDefaultSetting, which will be the same, but with additional user field (ManyToOne to User entity).
I tried to extend existing Setting entity class with one more field added. The problem is, as I looked at the schema update SQL, it created new table for the new entity, but without all the tables needed to ORM connections (mostly ManyToMany). Just one table with "scalar" fields.
So previously I've had setting table with int_value, date_value etc. but also setting_country and setting_language tables, linking ManyToMany relations. After creating child entity, Doctrine created only user_default_setting table with int_value, date_value etc. and additionally user_id column, but I can't see any relation/link tables.
I know I should've been do it with abstract base entity class, but at the time I started, I didn't know that and now part of the project is on production (don't look at me like that, I blame the client) and I don't want to change that "base" class now. Can I inherit everything from non-abstract entity class in a way it will work?
UPDATE: everything explained. See Cerad's comment. Thanks!

User Object in a one-to-one relationship using primary key shared with foreign key

Iterations of this question have been asked in the past, but this presents unique challenges as it combines some of the issues in one larger problem.
I have an entity(User) that is used as the user class in my application, then I have another entity (UserExtra), in a one-to-one relationship with the user entity, UserExtra's id is the same as User. The foreign key is the same as the primary key.
When the user object is loaded (say by $this->getUser() or by {{ app.user }}, the UserExtra data is also loaded through a join. The whole point of having two entities is so I don't have to load all the data at once.
I even tried defining a custom UserLoaderInterface/UserProviderInterface Repository for User, making sure that refreshUser and loadUserByUsername would only load the User data (I'd like for the UserExtra data to sit in a proxy unless I explicitly need it) but when Doctrine goes to Hydrate the object, it issues an extra query to load the UserExtra data, thereby skipping the Proxy status.
Is there a way out of this?
there are many solution for your issue:
1) Change the owning side and inverse side http://developer.happyr.com/choose-owning-side-in-onetoone-relation - I don't think that's right from a DB design perspective every time.
2) In functions like find, findAll, etc, the inverse side in OneToOne is joined automatically (it's always like fetch EAGER). But in DQL, it's not working like fetch EAGER and that costs the additional queries. Possible solution is every time to join with the inverse entity
3) If an alternative result format (i.e. getArrayResult()) is sufficient for some use-cases, that could also avoid this problem.
4) Change inverse side to be OneToMany - just looks wrong, maybe could be a temporary workaround.
5) Force partial objects. No additional queries but also no lazy-loading: $query->setHint (Query::HINT_FORCE_PARTIAL_LOAD, true) - seams to me the only possible solution, but not without a price:
Partial Objects are a little bit risky, because your entity behavior is not normal. For example if you not specify in ->select() all associations that you will user you can have an error because your object will not be full, all not specifically selected associations will be null
6) Not mapping the inverse bi-directional OneToOne association and either use an explicit service or a more active record approach - https://github.com/doctrine/doctrine2/pull/970#issuecomment-38383961 - And it looks like Doctrine closed the issue
this question may help you : one to one relation load

Symfony2, Doctrine and data domain

In a Symfony2 project with Doctrine as ORM, I have many entities dedicated to store data domain.
According to your experience:
which is the best naming convention for this data domain entities (for instance, is good to name "ProvinceDomain" the entity that will store all the province values)?
do you put data domain entities in a specific folder (for instance "Entity/DataDomain")?
do you prefer a prefix (for instance "domain_") or a suffix (for instance "table_name_domain") to name the domain data tables? Or do you use some other naming convention?
Thank you very much.
1)
I think that the correct name is Province. "Domain" is like a role. IMHO it doesn't have to be in the name. So, the full name could it be: CoreBundle/Entity/Province or xxx/Entity/Core/Province.
2)
In some projects I placed that kind of entities in a folder "Entity/Core".
At other times I have solved it in a specific bundle, for example, "CoreBundle/Entity".
3)
I see well that you call tables like "table_name_domain". Note that table is data, and it is not bad to categorize information as "domain"

Entity for table not managed by Doctrine?

So I'm using Symfony 2 with Doctrine 2 for a new web application but we have a few common tables shared among different applications.
We need to access these tables (read-only, there would be no updates) but I don't want Doctrine to manage them. My vision is to create an entity for it so Doctrine can use it, including relations to it, but not have it do create/alter table statements when I do doctrine:schema:update.
Am I overthinking this?
Create your entities (manually or using generator) and mark them as readOnly

Symfony2: loading user roles from database

I'm running into a problem with the Symfony2 Security system, particularly when trying to load Roles from a database. Before going further, I am aware of FOSUserBundle, but at the moment, in an effort to better understand the Symfony2 framework, I want to try and make my bundle work using Symfony2 components only. TL;DR -> please don't tell me to just use the FOSUserBundle. :-)
I have 3 entities configured in my bundle, Accounts, AccountsRoles, and AccountsRepository.
src\RedK\Core\IndexBundle\Entity\Accounts.php
http://pastebin.com/0VgXvtJp
src\RedK\Core\IndexBundle\Entity\AccountsRoles.php
http://pastebin.com/GiKNnYg3
src\RedK\Core\IndexBundle\Entity\AccountsRepository.php
http://pastebin.com/SVuMVdpN
MySQL demo_template.accounts Table
http://pastebin.com/YzmjD9e4
MySQL demo_template.accounts_roles Table
http://pastebin.com/Ybwr4f7y
All aspects of the bundle were working correctly (registration, confirmation, password reset, and login) before I attempted to add the loading of user roles from a database. When I simply set the role to array('ROLE_USER') via the getRoles() { return array('ROLE_USER') }, authentication worked and the user successfully logged into the site.
However, upon attempting to integrate roles from the database, I receive the following error, which I understand is an instance of AuthenticationException:
Notice: Undefined index: id in /home/humplebert/Websites/www/template/vendor/doctrine/lib/Doctrine/ORM/Query/SqlWalker.php line 804
Stack Trace
http://pastebin.com/Sr5RvZaY
The exception is only generated when I modify the query in AccountsRepository and remove
the "->select()" and "->leftJoin()" components. In looking at the Stack Trace, around line 16 on the pastebin.com link, it appears I have all sorts of "crazy" happening with regards to the many-to-many mapping in the BasicEntityPersister.
I've searched high and low in my Entity classes for any reference to plain "id" and can find none. I've noticed that if I change the names of my "ID" columns in my entities to just "id" (i.e. replace "AccountsID" with "id" in src\RedK\Core\IndexBundle\Entity\Accounts) the error goes away (and is replaced with another error, more on that in a moment).
Question 1)
Is there something blatently wrong with my Entities to be generating the "Undefined index: id" error I am receiving? If not, does Symfony2/Doctrine2 require that Auto-Increment columns in be labeled "id"?
As I have continued to tinker, I decided to try renaming my table ID columns to "id". Therefore, src\RedK\Core\IndexBundle\Accounts replaces AccountsID with just "id". And likewise, src\RedK\Core\IndexBundle\AccountsRoles replaces RolesID with just "id". Upon doing so, the "Undefined index: id" error goes away. However, I am presented with a new error: "table or view demo_template.accounts_accountsroles does not exist". Well of course it doesn't exist, I don't have a table defined as accounts_accountsroles. I have two tables, accounts and accounts_roles.
Question 2)
In order to use the Symfony2/Doctrine2 tools for importing user roles from a database, what rules are there regarding the naming of the tables? Based on the error I received, it seems that some form of concatenation is taking place. Or have I just simply screwed up my annotations somewhere along the line?
Any help would be greatly appreciated.
Regarding Question 1) the short answer is no! For the long answer see section 5.3 Mapping Defaults in the Doctrine Association Mapping documentation:
It states that if you use this short annotation:
/** #ManyToMany(targetEntity="Group") */
private $groups;
"In that case, the name of the join table defaults to a combination of the simple, unqualified class names of the participating classes, separated by an underscore character. The names of the join columns default to the simple, unqualified class name of the targeted class followed by “_id”. The referencedColumnName always defaults to “id”, just as in one-to-one or many-to-one mappings."
You can override the defaults by providing more detailed many to many annotations (see link above) and therefore avoid the id error.
Regarding Question 2) the concatenation is correct. Many to many relationships require a third 'junction' table. The Doctrine paragraph above explains how the name of this table is generated.
I don't know why the 'table ... does not exist' error is occurring for the junction table as the annotations look ok to me. It appears as though your database schema is somehow out of sync with your annotations.
I implemented a solution, above FOSUserBundle and described it here
After implementing Role access throug Doctrine you still need to make a RoleHierarchy service aware of it.

Resources