# Combination of @OnRemove and ordinary cascading

**URL:** <https://discourse.hibernate.org/t/combination-of-onremove-and-ordinary-cascading/8145>\
**Category:** Hibernate ORM\
**Created:** [August 18, 2023, 10:24pm UTC](https://discourse.hibernate.org/t/combination-of-onremove-and-ordinary-cascading/8145 "2023-08-18T22:24:23Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![virt](https://avatars.discourse-cdn.com/v4/letter/v/f6c823/32.png) [@virt](https://discourse.hibernate.org/u/virt)\
**Post date:** [August 18, 2023, 10:24pm UTC](https://discourse.hibernate.org/t/combination-of-onremove-and-ordinary-cascading/8145/1 "2023-08-18T22:24:23Z")

</div>

I can’t seem to get cascading for entity removal working. Because of the way my Data is structured, I have to use a combination of `@OnRemove(action = ...)` and normal cascading (e.g. `@OneToOne(cascade = ...)`). To better illustrate the problem, here are a few entities as an example:

```java
@Entity
class User {
    @Id
    String username;
}

@Entity
class Post {
    @Id
    @GeneratedValue
    UUID id;

    @ManyToOne
    @OnDelete(action = OnDeleteAction.CASCADE)
    @JoinColumn(name = "user")
    User user;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "attachment")
    Attachment attachment;
}

@Entity
class Attachment {
    @Id
    @GeneratedValue
    UUID id;

    String content;
}

```

As you can see, I have two unidirectional relationships, from the `Post` to the `User` and from the `Post` to the `Attachment`. **I do not want to have a bidirectional relationship between either of them** , because a `User` is included in very many `Post`-like entities, and an `Attachment` can be used by virtually anything.

You can also see the cascading I am trying to implement. It should work like this:

1. I delete a `User`.
2. All `Post`s of the `User` are deleted, specified by `@OnDelete(action = OnDeleteAction.CASCADE)`
3. The `Attachment` of every `Post` is in turn deleted, specified by `cascade = CascadeType.ALL` in the relation Annotation.

However, this does not work as anticipated, as the user `User` and associated `Post` entities are deleted, but the `Attachments` are not. This is problematic, since I then have orphaned `Attachment`s in my database, which I would have to remove manually. I have also tried specifying `orphanRemoval = true`, but that doesn’t do anything either.

I have a hunch on why this does not work as expected, but please correct me if I am being wrong:  
As far as I know is the deletion of entities with `@OnDelete` handled on the database itself, specified by the foreign key constraint (something like `constraint ... foreign key (user) references user (username) on delete cascade`). However, the cascading using `cascade = CascadeType.ALL` is managed by Hibernate itself and is not done by the database.  
So what I think what happens is that Hibernate tells the database to delete the `User`. The database then goes on deleting the `User`, following the foreign key constraint, also deleting the `Post`s. But Hibernate does not know that these `Post`s were deleted, so no further cascading, which would be handled by Hibernate, happens.

So, my questions are the following:  
How could I make this work as expected?  
Is there a way of using `@OnRemove` which is not done over the database?  
Or the other way round, can I cascade the rest also over foreign key constraints?

I am using Spring Boot 3.1 with Hibernate 6.2.

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [August 21, 2023, 8:50am UTC](https://discourse.hibernate.org/t/combination-of-onremove-and-ordinary-cascading/8145/2 "2023-08-21T08:50:34Z")

</div>

> How could I make this work as expected?

You’d need a database trigger that removes attachments on delete of a row, or a cleanup job/task that looks e.g. every X days for attachment rows that have no matching FK column entry.

> Is there a way of using @OnRemove which is not done over the database?

No, the annotation is there to configure the foreign key constraint.

> Or the other way round, can I cascade the rest also over foreign key constraints?

You could use the metamodel to find all entities which have an association to your `User` entity and delete these first. You can do that in a generic fashion, but I can tell you from past experience, that it is usually easier to simply mark the user as deleted with a flag and anonymize the user’s personal data e.g. by changing the name to ` ***** ` or something like that. You have to think if you really want to delete posts and attachments of something that might have use to the organization to which a user belonged to.
