I am so new to Doctrine 2 and not that good with regards to database table relationships. I understand the way of how Many to One, One to Many, One to One and Many to Many relationship works. I am just confused with this error I got below from generating database tables using the doctrine CLI.
[Doctrine\ORM\ORMException]
Column name `id` referenced for relation from Kent\Entity\DoctorSpecialties towards Kent\Entity\Doctors does not exist.
Please see this github link to view my entities. (Doctors.php & DoctorSpecialties.php)
https://github.com/aldee07/Doctor-Finder/tree/development-september/library/Kent/Entity
Note: I am using Zend Framework 1.11.12
That are the annotations you must put on DoctorSpecialties class
#ManyToOne(targetEntity="Doctors")
#JoinColumn(name="doctor_id", referencedColumnName="doctor_id")
in Many to many relationship you have to give the reference to the third forignkey table
so change this
/**
*
* #var Doctors
* #ManyToMany(targetEntity="Doctors", mappedBy="specialties")
* #JoinTable(name="doctor_specialties")
*/
protected $doctors
hope this helps
I think is better you look here:
http://www.doctrine-project.org/jira/browse/DDC-2646?page=com.atlassian.jira.plugin.system.issuetabpanels:changehistory-tabpanel
Related
I want to add the option onDelete="CASCADE" on one of my attributes via the #JoinColumn annotation:
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\Product",mappedBy="category",fetch="EAGER")
* #ORM\JoinColumn(onDelete="CASCADE")
*/
private $products;
But when I try to update with php bin/console doctrine:schema:update --force , I always get:
nothing to uptade - database already sync.
I tried to add some other attributes and I got the same issue. However, if I intentionally add a mistake I get an error as expected.
How can I fix this?
The #OneToMany annotation is the one you use on the inverse side of your many-to-one association. The table storing the entities on this side of the association does not hold any foreign key pointing to the table storing your Product entities, thus there is no "join column" there.
The documentation states the following about #JoinColumn:
This annotation is used in the context of relations in #ManyToOne, #OneToOne fields and in the Context of #JoinTable nested inside a #ManyToMany.
In your case, the annotation does not apply to any column at all and consequently, your database does not need to be updated.
If you wish to have Product entities related to a given Category removed through cascade operations by your database, you have to add a #JoinColumn(onDelete="CASCADE") on the owning side of the association, next to the #ManyToOne annotation of the category attribute of Product.
I am using Symfony and Doctrine
This might be a simple question but i cannot seem to find the answer to it...
How can i reference the join-table of a many-to-many association in a querybuilder ?
I have 2 entities: Article and Tag with a many-to-many bidirectional relation
this creates the extra join-table :
article <-> article_tag <-> tag
I can reference the article table by selecting it from the Article Entity :
$this->_em->createQueryBuilder();
->select('a')
->from('Acme\DemoBundle\Entity\Article','a')
And i can reference the tag table by selecting it from the Tag Entity :
$this->_em->createQueryBuilder();
->select('t')
->from('Acme\DemoBundle\Entity\Tag','t')
Now how can i select things from the join-table ? There is no entity for it...
You cant interact with this table. Doctrine will handle it, and like Roger Guasch said on the comments, you have to create accessors to the corresponding entities.
If you need to interact directly with this entity, you must define it by yourself, threating the m-n table as an entity. Then you can make reference to it.
Hope it helps!
I have problem which is easy to solve with pure SQL but I need to solve it with Doctrine in YAML.
I have well known db tables users and friends. Where users table has primary key user_id and friends has friend_id and friend_with_id which uses user_id from table user. My problem starts when I need to add there one more column mood. With SQL I add to table friends onemore column named mood and it's done with doctrine I can't find any solution.
For better understanding I add db scheme:
I dont see any self-reference relationship here. Both friend_id and friend_with_id points to users.user_id. What I see is, two one-to-many relationships from the user side OR two many-to-one relationships from the friends side.
So, there will be two ArrayCollection objects (ManyToOne) in the Friend entity corresponding to friend_id and friends_with_id. Similarly two ArrayCollections (OneToMany) on the User entity, namely, myFriends and friendsWith.
I'm having some problems with the following...
I have a table with phone numbers. I want to use the same table for both users and companies. A user can have several phone numbers and a company too. So i want a One to many unidirectional relationship with two different join tables. One linking phone numbers to users, the other linking phone numbers to companies.
This is solution following the doctrine2 manual chapter 5.9 found here: (click)
My users entity holds this code:
/** #ORM\ManyToMany(targetEntity="Application\Entity\PhoneNumber")
* #ORM\JoinTable(name="user_phone_number_linker",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="phone_number_id", referencedColumnName="id")}
* )
*/
protected $phone_numbers;
I use a unidirectional one to many because the thing is I can't make a bidirectional one because if I refer back to the user I cannot use the same phone number entity class for the company. Now it all works fine, but when I delete a phone number I get the following error:
An exception occurred while executing 'DELETE FROM phone_number WHERE id = ?' with params {"1":1}:
SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (database/user_phone_number_linker, CONSTRAINT user_phone_number_linker_ibfk_11 FOREIGN KEY (phone_number_id) REFERENCES phone_number (id))
If I set the ON DELETE CASCADE value manually in the database it works fine, but this is not the idea of using doctrine2 and I think I should be able to solve it within the code without going to my phpMyAdmin panel. Somehow the cascading from the phone number towards the join table should be initiated on deletion, but without making a reference back to the join table from the phone_number entity.
Hope someone smart can help me solve this.
EDIT
In the meantime I learned a lot more about Doctrine2 and reviewing my old question made me realize that this is not a correct way to store several phoneNumbers in one table in the first place. To be able to store user phone numbers and company phone numbers in the same table I should use table inheritance with a discriminator column. The column should hold some user/company discriminator.
Because of this column the doctrine ORM will "know" if that phoneNumber is actually a user or a company phone-number. I need to make two different entity definitions following the single table inheritance mapping principles from the doctrine 2 specs.
One class UserPhoneNumber will have a many-to-one relationship with User the other called CompanyPhoneNumber a one-to-many relationship with Company. I don't necessarily need a join column, the user_id or company_id columns can be in the phone-number table. In the User class the Company association is omitted and in the Company class the User association is omitted (database should allow null values for those columns).
If I do use a join table it is according to the one-to-many unidirectional with join table description in the Doctrine2 specs
READ MORE
Otherwise you can also read more on associations and cascade issues here on this elaborate Doctrine2 in depth website.
As you said, your relation is unidirectional. You've defined a relation from Users to PhoneNumbers. The cascade delete will work when you delete a User, it will remove all rows in user_phone_number_linker because that's the relation you've defined.
If you want to do it the other way, you've got to create a relation from PhoneNumbers to Users. Doctrine needs it to work for you. But you have the problem that the entity is shared by two other entities, Users and Companies.
Keep in mind that entities are objects, not tables. So you could try to create two entities to the same table, one named PhoneNumberUsers and the other PhoneNumberCompanies. This way you'll be able to create the needed relation to do the cascade delete. I haven't tested by myself, but I think it could work.
By the way, you can remove the oncascade parameter on the Users' entity join table. I've the same scenario as you with users and roles, and I haven't used it. I think it's only needed when you want to cascade from entity to entity. I'm not sure about that, but that's what I've been experiencing until now.
My bad,
The phone number user relationship is regarded a Many-To-Many relationship, so if want to remover the phone number I should not only remove the phone number itself, but I have to explicitly remove the phone number from the user as well. So in the Controller like this:
// Remove the phone number user connection from the database
$user->removePhoneNumber($phone_number);
// Remove the phone number from the database
$em->remove($phone_number);
I just thought the unique restriction which makes the relationship to a unidirectional One-To-Many would be enough to make doctrine take care of it. That was not correct.
I have a "Product" entity with many "Video" entities, and I only need a unidirectional #OneToMany with foreign key (one product, many videos). My Product-side "key" is not primary or unique, which is why I need it to be unidirectional (eg, "select * from videos where product_family = 2143")
I'm using Doctrine 2.1
Is there yet a way to do uni-directional #OneToMany with only a foreign-key in Doctrine 2.1? If not, soon?
UPDATE: I found a relevant quote from Roman Borschel on May 2010:
"this would need quite some special-case handling in many places. In the light that there are 2 reasonably good alternatives (mapping through a jointable or simply making the association bidirectional) we do not consider this something that really needs to be done."
Has this opinion by the Doctrine2 team changed?
OneToMany by design has the related ID on the "Many" side of the relationship. So to make the child table relate to the parent without an additional field in a join table is not possible.