Hi doctrine 2 lovers,
As I promised in my previous post, here I came with my very next post, which is the relationship mapping using Doctrine 2. Before going any further make sure that you have read my previous post, which is about table mapping using Doctrine 2. And I assume you have at least a little bit of knowledge about using Doctrine 2 YAML syntaxes and indentation, which is also highlighted in my previous post. Ok, enough about my previous post, now let’s get back to the today’s topic 🙂
As you know, or will know in a moment, there are two major types of relationships between tables. Which are,
And with above two types, the relationship could be,
In this post I will be discussing on all eight combinations starting on Unidirectional/Bidirectional relationship types of one-to-one.
Unidirectional – One To One
In simple terms, one-to-one means, one row of a table, relates only with one and only one row of another table. Take a look at the image below,
As you can see, one product can have (at most) one product details or simply none. But NOT more than one product details per product. When it comes to unidirectional one-to-one mapping in Doctrine 2.x, it’s really easy and straightforward, so you need to know following things.
- Parent table – ‘product’ and the target table – ‘product_details’.
- Column names of the parent table and target table which needs to be linked.
(Typically primary_key column of the target table mapped against the parent table, we’ll be discussing these thing below)
Now, here’s the Doctrine ORM in YAML, for the above mapping.
Few things to remember in here,
- Correct One to one mapping syntax is ‘oneToOne’ NOT ‘OneToOne’.
- ‘product_details’ text after oneToOne is not actually the name of the target table, although it is identical to the target table name. This ‘product_details’ name is an alias used by Doctrine when being referred back by a bidirectional relationship (discussed next).
- Target entity is the name of the target table’s entity (including the directory path if not in the same directory), NOT the table name.
- Name bit can be ignored if you followed standards. Because in Doctrine, as a standard it expects, the name of the field (column) in the parent table which is being referred to a target table is in this format, ‘<target_table name>_id’, so in our example it’s ‘product_details_id’. So if you follow these standards, life will be much easier. However I put this for your additional information.
- Referenced column name is the field of the target table, which is usually the primary key.
Now let’s move to the bidirectional type of relationship in the same one-to-one instance.
Bidirectional – One To One
The major difference from here to the counter part which is unidirectional is the call back declaration from the target ORM file. In the above example you saw only the parent table establishing the unidirectional relationship. In here, with the above declaration we add the relevant relationship part to the target table which is the ‘product_details’ table. Take a look at the ORM specification for ‘product_details’ table below, in YAML format.
In here, I will not be discussing the same bits which I have discussed above. But still few things to remember in here,
- The text ‘product’ is once again NOT the table name but an alias which is being used by the Doctrine.
- Notice the ‘inversedBy‘ statement, which is in red. This is the statement which says that this is a bidirectional relationship. So, it expects a relationship calling back from the table ‘product’, which is named (aliased) as ‘product_details’. If you quickly look at the code above (product table ORM above), you will immediately notice that ‘product_details’ is same as the alias which is being used in the ProductDetails entity. This is a highly important point that you need to remember all times.
So I hope you had a good understanding of both unidirectional and bidirectional one-to-one relationships so far. Let’s move on to one-to-many relationships next. So my next post will be one-to-many relationships for both ways. Stay tuned. Cheers! 🙂