How about orphanRemoval in many to one relationships? #5759

Open
opened 2026-01-22 15:16:56 +01:00 by admin · 3 comments
Owner

Originally created by @bizmate on GitHub (Nov 3, 2017).

I have stepped into a use case where i think orphanRemoval could be extended for manyToOne relationships. My view on orphanRemoval is that through the ORM it should guarantee that no orphan is left in the db. The logic of my entities is approximately that A, B (, C etc) might all depend on dependency entity D. D instances are always created through owning entities A, B . When no instance of A or B references a D then that one becomes an orphan.

A practical example is an ingredient in a recipe . You create recipes and while doing this add the ingredients. If an ingredient is not used anymore in none of the recipes then it is an orphan in db terms.

To further details this with an example I created this repository with an automated test.
https://github.com/bizmate/doctrine-orphan-remove (README instructions are very straight forward, only make and docker are needed to run it)

I am interested to hear your thoughts

Originally created by @bizmate on GitHub (Nov 3, 2017). I have stepped into a use case where i think orphanRemoval could be extended for manyToOne relationships. My view on orphanRemoval is that through the ORM it should guarantee that no orphan is left in the db. The logic of my entities is approximately that A, B (, C etc) might all depend on dependency entity D. D instances are always created through owning entities A, B . When no instance of A or B references a D then that one becomes an orphan. A practical example is an ingredient in a recipe . You create recipes and while doing this add the ingredients. If an ingredient is not used anymore in none of the recipes then it is an orphan in db terms. To further details this with an example I created this repository with an automated test. https://github.com/bizmate/doctrine-orphan-remove (README instructions are very straight forward, only make and docker are needed to run it) I am interested to hear your thoughts
Author
Owner

@lcobucci commented on GitHub (Nov 26, 2017):

@bizmate I kind of have mixed feelings about this... I'm not sure if it should be up for the ORM to handle orphan removals for that type of associations.

TBH I believe that is related to a design smell. For example, the "ingredient in a recipe" use case you provided should be seen (and mapped) differently IMO. I believe that there's a missing association between a Recipe and an Ingredient, which defines the amount of particular ingredient on a recipe. I believe that we shouldn't remove existing ingredients because a recipe got deleted simply because it can be reused by a new recipe. Would be something like:

class Ingredient
{
    private $name;
}

class Recipe
{
    // 1-to-many association with `RecipeIngredient` (orphanRemoval=true)
    private $ingredients;
}

class RecipeIngredient
{
    // many-to-1 association with `Ingredient`
    private $ingredient;

    private $amount;
}

That's my 2 cents, but maybe the @doctrine/team-doctrine2 might think differently?

@lcobucci commented on GitHub (Nov 26, 2017): @bizmate I kind of have mixed feelings about this... I'm not sure if it should be up for the ORM to handle orphan removals for that type of associations. TBH I believe that is related to a design smell. For example, the "ingredient in a recipe" use case you provided should be seen (and mapped) differently IMO. I believe that there's a missing association between a `Recipe` and an `Ingredient`, which defines the amount of particular ingredient on a recipe. I believe that we shouldn't remove existing ingredients because a recipe got deleted simply because it can be reused by a new recipe. Would be something like: ```php class Ingredient { private $name; } class Recipe { // 1-to-many association with `RecipeIngredient` (orphanRemoval=true) private $ingredients; } class RecipeIngredient { // many-to-1 association with `Ingredient` private $ingredient; private $amount; } ``` That's my 2 cents, but maybe the @doctrine/team-doctrine2 might think differently?
Author
Owner

@bizmate commented on GitHub (Nov 28, 2017):

hi @lcobucci
thanks for the input but I think the choice should be the system designer's depending on business requirements. In each application it is up to business requirements if Ingredients should be kept or not. Normalisation and consistency would always indicate to remove data and entities that are not conceptually used.

Also in your case you are changing the use case. The mapping entity would need to exist if you need the amount. My example is just an example not to be linked with real meaning or expectation of what I would do in my kitchen.

Also I think that it would be perfectly acceptable to cascade/remove RecipeIngredients and Ingredients orphans if a Recipe is removed. Again there might be a specific reason at business level but then it is always a choice of the business to do this and the engineers/dev can always decide with a mapping in an ORM context. I certainly would not agree with a design that leaves useless orphan entries in my db

@bizmate commented on GitHub (Nov 28, 2017): hi @lcobucci thanks for the input but I think the choice should be the system designer's depending on business requirements. In each application it is up to business requirements if Ingredients should be kept or not. Normalisation and consistency would always indicate to remove data and entities that are not conceptually used. Also in your case you are changing the use case. The mapping entity would need to exist if you need the amount. My example is just an example not to be linked with real meaning or expectation of what I would do in my kitchen. Also I think that it would be perfectly acceptable to cascade/remove RecipeIngredients and Ingredients orphans if a Recipe is removed. Again there might be a specific reason at business level but then it is always a choice of the business to do this and the engineers/dev can always decide with a mapping in an ORM context. I certainly would not agree with a design that leaves useless orphan entries in my db
Author
Owner

@lcobucci commented on GitHub (Nov 28, 2017):

thanks for the input but I think the choice should be the system designer's depending on business requirements.

@bizmate you're definitely correct here, but what I meant is that I don't think this should be part of the lib at all. The complexity involved on supporting orphanRemoval for many-to-* associations is quite huge, specially when having multiple many-to-* associations on different entities to the same one (e.g.: entity A, B, and C have a many-to-one with D), is quite huge and the benefit is very little (also compared with the performance implications).

I certainly would not agree with a design that leaves useless orphan entries in my db

Then the ORM should give enough information for you to handle the specific needs of your model (which it does IMO).

@lcobucci commented on GitHub (Nov 28, 2017): > thanks for the input but I think the choice should be the system designer's depending on business requirements. @bizmate you're definitely correct here, but what I meant is that I don't think this should be part of the lib at all. The complexity involved on supporting `orphanRemoval` for `many-to-*` associations is quite huge, specially when having multiple `many-to-*` associations on different entities to the same one (e.g.: entity `A`, `B`, and `C` have a `many-to-one` with `D`), is quite huge and the benefit is very little (also compared with the performance implications). > I certainly would not agree with a design that leaves useless orphan entries in my db Then the ORM should give enough information for you to handle the specific needs of your model (which it does IMO).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5759