Doctrine 2 : Multiple relations between two tables - symfony

I have a problem more concerning database relations than Doctrine itself.
I have a table "project" and a table "project_data". My table "project_data" is ALWAYS linked to a project entry.
However, in my table "project", I can have two references to a project_data entry : project_data_id, and project_data_waiting_id. However, these references can be null and have no relation with the "project_id" that is set in project_data table.
Question :
How to define all these relations? I want to be able to have project entries without any project_data references.
How to handle it with Doctrine? I'm kind of new with Doctrine and with database design, and I am a bit lost between all the joins that I have to do between my tables.
I join you a diagram to have a better idea of what I want to do.
Thank you.

In this case I will give you two options (assuming project_data always has only one project):
First:
project
- id
- project_data_id
- project_data_waiting_id
project_data
- id
- name
In that case you can define two one-to-one relationsships on your project class. Look at http://docs.doctrine-project.org/en/latest/reference/association-mapping.html#one-to-one-bidirectional for more information how to handle this.
Second: option:
It's also possible to create a many-to-many relationship and give your project_data a status. It would look like this:
project
- id
project_data
- id
- name
- project_id
- status_id
project_data_status
- id
- name
In this case project will have a many-to-one relation with project_data and project_data will have a one-to-many relation with project_data_status. This solution gives you more flexibility. You can add as many project_data objects to project as you like.
How to define relations in doctrine2 can be found on the same page I already provided in this post.
Hopefully this will point you in the right direction.

Related

Symfony2, Doctrine OneToOne relations

I have table (let's name it "First") with columns id, userID, moonID, typeID. And another table (let's name it "Second") where is also column "typeID" and TypeName (simple example, basicly this table is a huge storage of data).
I need create simple relations with this two (entities) tables such way that i can simple create new entries in "First" table and remove\edit them. But i don't want to del\add\edit entries from "Second" table. So "Second" is untouchable at all, we just select data from "Second" by typeID of "First". How can i do this?
I want to see two entities and controller. Please help me with it.
Its very easy have a look at here
http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html
You will know what to do. they have examples over there.
By default Doctrine wont delete the linked side unless you do onCascade="Delete"
You can use OnDelete= Null if you want to make the linked is to null in case of deletetion of owning side

Entities associations across different managers

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.

Doctrine2 - How to persist the order of a collection?

Using Docrine2 entities, I have a "list" entity, with a manytomany relationship with "item".
I need to manipulate and save the order of the items in the list. I can't figure out how to accomplish this using Doctrine2. What I want is a joiner table that looks something like:
list_item
=========
list_id
item_id
sort_order
All I can find is this outdated to-do item: http://www.doctrine-project.org/jira/browse/DDC-213
Can I accomplish this using Doctrine? Or is there some other way I should be going about this?
Thanks.
Here is an exerpt from this docs section, that answers your question:
Real many-to-many associations are less common. [...] Why are many-to-many associations less common? Because frequently you want to associate additional attributes with an association, in which case you introduce an association class. Consequently, the direct many-to-many association disappears and is replaced by one-to-many/many-to-one associations between the 3 participating classes.

Link Tables - Code First - Entity Framework - Table-Mapping

I asked a related question previously on this forum. This question outlines the steps I have taken, different things I have tried and errors I have encountered. It might help someone.
Considering a mapping to a structure that involves a link table, it seems to me there is a quirk with Code First, Link Tables and TPH or perhaps just a lack of transparency.
I created a derived class with a [Table("")] attribute to map objects to the following sort of table structures:
(Case 1) Employees -> Attributes -> AttributeTypes
(Case 2) Employees -> EmployeeAttributeLink -> Attributes -> AttributeTypes
In the former case i achieved the results i wanted for TPH querying and saving. (I used data annotation attributes along with fluent api to map the derived classes to the correct discriminator id column).
However, in the second case I got this error:
'The entity types A and B cannot share table B because they are not in the same type hierarchy [OR] do not have a valid one to one foreign key relationship with matching primary keys between them. Need to have a 1-1 correspondence'
When I looked at the names of the tables that it was trying to map types to I could see it was confused. However I could not figure out what I was doing wrong as I had used the correct table mapping attribute above the inheriting classes (I didn't define all the sub types that could come from the discriminator - does that matter?).
I introduced some FK attributes trying to address the second part of the [OR] in the error message. This led me to new problems i.e. unable to determine principal/dependant... Then I tried to use the [InverseProperty] attributes... And then I started pulling my hair out.
Now, rolling back and removing the attributes, I decided not to rely on [Table("")] attribute and map the type to the table using the fluent api. This seems to work.
My question is: Why is it that the behaviour of the [Table("") ] attribute and the ToTable function on the fluent API behave differently? I would have thought they are interchangeable
Thanks

EF4.1 CodeFirst: Add field to join table

I am using EF 4.1 RC and CodeFirst/POCO to build my database by code.
Imagine having a many-to-many relationship like Teachers-Students (one teacher can have many students, and one student may have many teachers). Accordingly I have two POCOs: (1) Teacher and (2) Student.
When EF creates the corresponding tables you will end up with three tables: (1)Teachers, (2) Students and (3) an extra join table. The join table contains exactly two fields: a Teacher_ID and a Student_ID.
I was wondering if I had any chance to add an extra field to the join table, e.g. "Grade" (the grade a certain teacher gives a certain teacher)?
Currently I have no idea how to achieve this with only two POCOs.
So I guess all I can do is create a third POCO (for the join table) manually, am I right? That will certainly work, but then I am losing nice navigation properties like oneTeacher.Students.First(), etc. That is the main reason why I am still looking for another way.
That's correct, and does not only apply to Code-first. If you have extra fields in your joining table, you will have it mapped as an entity. And vice-versa, if you want an extra field in your joining table, you need to create a new entity and have zero-or-one-to many or one-to-many navigation properties to the Teacher and Student entities. In any case, you lose the comfort of accessing Teacher.Students and Student.Teachers and have to go via the intermediate entity.
Alternatively, you could think about modeling the DB structure differently and extracting the extra info into the Teacher or Student or a fourth entity. But that depends entirely on your scenario.
Yes, the join table cannot have a payload or you need to break it down to 2 one to many association which will result in creating a third entity to hold the PKs as well as the additional properties.
This is an idea I still haven't found time to try it out. Maybe you can keep your Student and Teacher classes as they are, and add a third POCO StudentGrade with properties Student, Teacher and Grade. Then you'll have to use the fluent API to make sure that both the many to many relation between Student and Teacher and the StudentGrade class map to the same table.
Hope that helps

Resources