0

I have more experience with SQL databases than I do with Symfony and am hoping someone can clarify the association mappings on how Doctrine connects the database to Symfony.

Taking a one-to-many mapping between Category and Product as an example:

I have very little need to record productIDs as a long string in each category record and I assume that having it is an unnecessary overhead. If I really needed to get a list of all products in a category record in the future though then I assume I could just manually query it still?

By extension, to get the above, I would need a unidirectional many-to-one association. If this is the case though, then would I still (and how would I?) be able to control such things as on delete cascade if required?

Bendy
  • 3,506
  • 6
  • 40
  • 71
  • "I have very little need to record productIDs as a long string in each category record and I assume that having it is an unnecessary overhead." Symfony does **not** do this, just to clarify. – martinczerwi Dec 11 '15 at 09:59
  • Hi @martinczerwi - how do you mean? Are you referring to `arraycollection` instead of `string`? My thought was that it's all extra data that in the vast majority of use cases that is redundant to me. Example being `features` variable here: http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-many-bidirectional – Bendy Dec 11 '15 at 10:07
  • If you read my answer you will understand. @martinczerwi is right. Doctrine does not add a column inside the category table. The `features` property only exist in the **object model**. not in the **database model**. – Wilt Dec 11 '15 at 10:35

1 Answers1

2

I think you are not totally understanding how this works in Doctrine. I hope this helps:

If you do a one-to-many between your Category and Product (one category has many products) with doctrine then it means that all you need is a category_id column in your product table (product is in this case the owning side of the relationship). You can make the relationship bi-directional without any consequences for the category table. Doctrine will allow you to get the products for a category easily by doing:

$category->getProducts();

In the background a query will be performed where all products with matching category_id column are resolved from your database and added to the products collection in the Category entity.

Check the example in the docs. It is exactly like yours, but then a one-to-many between product and features.

To prevent all products from loading when querying your category you can mark the inverse side as fetch="EXTRA_LAZY".

If you still have questions after this, just leave a comment.

Update:

So to make it very clear: doctrine does not add a column inside the category table. In your case the products property only exist in the object model not in the database model.

Wilt
  • 41,477
  • 12
  • 152
  • 203
  • Thanks very much @Wilt - I think/hope I follow...! So are you saying that all the `product_id`s are not stored in the Category table and this is an additional query that is made in the background when generating a Category object? My specific case is that I have a `category` style table that is just a lookup table - the table it maps to has literally 10,000's of mappings so capturing these have no value to me. – Bendy Dec 11 '15 at 10:34
  • Yes, I added update to make it even more clear for you and others with same question... – Wilt Dec 11 '15 at 10:37
  • Thanks for the clarification between the **object model** and **database model**. What is the correct way to deal with `on delete cascade`s? Should that be declared in the doctrine associations for the database model? – Bendy Dec 11 '15 at 10:44
  • It depends on your preference. I normally let doctrine handle it, since it feels like I have more control. Another advantage is that if you make changes to cascade operations you don't need to update your database model... Some people add both, but I think it is a bad idea to do that. – Wilt Dec 11 '15 at 10:47
  • @Bendy read [this answer](http://stackoverflow.com/a/6334710/1697459) it will help you understand... – Wilt Dec 11 '15 at 10:51
  • Just for clarification...a bidirectional join (which populates the `products` property in the **object model**) will not increase the database size - BUT it could slow performance by using extra memory that is not required - is this right? In such a case, we could avoid the memory use with a ManyToOne unidirectional mapping – Bendy Dec 11 '15 at 12:48
  • @Bendy, You don't have to worry about performance as long as you set the many side of the association to `fetch="EXTRA_LAZY"`. Having a bi-directional relationship will prove you very useful when querying your object model. I would advise you to use bi-directional where you can. Only use uni-directional if you are **never** interested in the collection on the inverse side (in this case your products)... – Wilt Dec 11 '15 at 13:02