Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relationships not updated correctly #9

Open
Jcalcaldev opened this issue Feb 23, 2024 · 3 comments
Open

Relationships not updated correctly #9

Jcalcaldev opened this issue Feb 23, 2024 · 3 comments

Comments

@Jcalcaldev
Copy link

I have a Foo entity with a OneToOne relation to a Bar entity.
When hard-deleting Foo, Bar is deleted due to having deleteRule: 'cascade'.
When soft-deleting Foo, Bar is not deleted and it's deletedAt property is not updated, only Foo's deletedAt.

HOWEVER: If I attempt to fetch Bar, the orm doesn't find it, even when its deletedAt property is still undefined. If I disable filters, it's fetched correctly.

So it seems it's working half way. Am I missing something? Is there a standardized way I should be cascading soft deletions? I'm only using deleteRule: 'cascade'. No orphan removal.

@Jcalcaldev Jcalcaldev changed the title Relationships not updated correctly. Relationships not updated correctly Feb 23, 2024
@Char2sGu
Copy link
Owner

Hey @Jcalcaldev thanks for the feedback. I'm extremely occupied these days. Will look into it after March 1st.

@Char2sGu
Copy link
Owner

I'm not pretty sure whether the deletedAt property of the relation entity should be updated. Currently, since we have filtered out all the deleted Foo entities from the queries, the Bar entity is expected not to appear in the query result, and I think it is an acceptable behavior since it makes it easier to recover soft-deleted entities - you only need to set deletedAt to undefined on one entity.

I do understand that it might be confusing at the data level, since the entity is in fact soft-deleted but its deletedAt property does not have a value, but currently I don't find a good reason to update the behavior.

Please let me know if there are any other troubles caused by this behavior.

@ViktorVendolsky
Copy link

I'm not pretty sure whether the deletedAt property of the relation entity should be updated. Currently, since we have filtered out all the deleted Foo entities from the queries, the Bar entity is expected not to appear in the query result, and I think it is an acceptable behavior since it makes it easier to recover soft-deleted entities - you only need to set deletedAt to undefined on one entity.

I do understand that it might be confusing at the data level, since the entity is in fact soft-deleted but its deletedAt property does not have a value, but currently I don't find a good reason to update the behavior.

Please let me know if there are any other troubles caused by this behavior.

Since this behavior is acceptable (marking only parent entity as deleted) for REST API in GraphQL you need to soft delete even child entities, since you can go from child entity to parent entity in GraphQL query, which when parent is soft deleted can lead to unpredictable behavior.

I managed to find a workaround for this using orphan removal.

Example:

class ParentEntity{
//some properties

@OneToMany(() => ChildEntity, (childEntity) => childEntity.parentEntity, { orphanRemoval: true })
childEntities: ChildEntity[]
} 

class ChildEntity{
//some properties

@ManyToOne(() => ParentEntity)
parentEntity: ParentEntity
} 

then in your repo you can do something like this

async removeParent(id: string) {
    const parent = await this.parentRepo.findOne({ id } , {
      populate: ['*'] // * symbol populates all relations (even nested), allowing for orphan removal to work properly
    });
    this.em.remove(parent);

    await this.flush();
}

The above code will soft delete all child entities of parent entity and child entities of child entities an so on

This works, because orphan removal is triggered by the ORM and not DBMS allowing this library to work correctly.
However keep in mind that this might result in unwanted soft deletions so it's best to populate only relations you want deleted by hand.

e.g.

instead of

populate: ['*']

use

populate: ['childEntites.anotherNestedEntity']

For more information on this matter I highly recommend looking at this discussion, where author of MikroORM explains it

I'm aware that this isn't the optimal solution, but rather a hacky workaround but it works

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants