# @SoftDelete and Jakarta @PreRemove

**URL:** <https://discourse.hibernate.org/t/softdelete-and-jakarta-preremove/10354>\
**Category:** Hibernate ORM\
**Created:** [September 19, 2024, 11:25am UTC](https://discourse.hibernate.org/t/softdelete-and-jakarta-preremove/10354 "2024-09-19T11:25:53Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![StringKe](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/stringke/32/3482_2.png) [@StringKe](https://discourse.hibernate.org/u/StringKe)\
**Post date:** [September 19, 2024, 11:25am UTC](https://discourse.hibernate.org/t/softdelete-and-jakarta-preremove/10354/1 "2024-09-19T11:25:53Z")

</div>

I have tried the new @SoftDelete annotation. This works so far, but unfortunately Jakarta @PreRemove is not triggered by it.

Or am I doing something wrong? Is there another annotation to fill e.g. a DeletedAt field with the date of the Delete?

---

<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:** [September 20, 2024, 8:22am UTC](https://discourse.hibernate.org/t/softdelete-and-jakarta-preremove/10354/2 "2024-09-20T08:22:04Z")

</div>

You’re not doing anything wrong, this sounds like a bug to me. Please try to create a reproducer with our [test case template](https://github.com/hibernate/hibernate-test-case-templates/blob/master/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java) and if you are able to reproduce the issue, create a bug ticket in our [issue tracker](https://hibernate.atlassian.net) and attach that reproducer.

---

<div class="post-metadata">

**Author:** ![Faro\_Aaron](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/faro_aaron/32/3208_2.png) [@Faro\_Aaron](https://discourse.hibernate.org/u/Faro_Aaron)\
**Post date:** [November 26, 2024, 12:21pm UTC](https://discourse.hibernate.org/t/softdelete-and-jakarta-preremove/10354/3 "2024-11-26T12:21:30Z")

</div>

I have the same aim. I found that it is not @PreRemove not work. @PreRemove worked but the data not update to the database (Maybe because hibernate think it is a remove operation). I use EntityManager in EntityListener to sovle it. like follow:

```java
@ToString(onlyExplicitlyIncluded = true)
@Getter
@MappedSuperclass
@EntityListeners({AuditingEntityListener.class, DeletedDateEntityListener.class})
@SoftDelete
public abstract class AbstractEntity extends AbstractAggregateRoot<AbstractEntity> implements Serializable {

    @Serial
    private static final long serialVersionUID = 6798146935361596394L;

...

    @Setter
    @Column(name = "deleted_date")
    private Instant deletedDate;

...
}

```

```java
@RequiredArgsConstructor(onConstructor_ = @Lazy)
public class DeletedDateEntityListener {

    private final EntityManager entityManager;

    @PreRemove
    void preRemove(final Object object) {
        if (object instanceof final AbstractEntity entity) {
            entity.setDeletedDate(Instant.now());
            entityManager.merge(entity);
            entityManager.flush();
        }
    }

}

```

---

<div class="post-metadata">

**Author:** ![Faro\_Aaron](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/faro_aaron/32/3208_2.png) [@Faro\_Aaron](https://discourse.hibernate.org/u/Faro_Aaron)\
**Post date:** [November 27, 2024, 10:44am UTC](https://discourse.hibernate.org/t/softdelete-and-jakarta-preremove/10354/4 "2024-11-27T10:44:28Z")

</div>

I found the previous code with cascade will have error, finally I use jdbc to operate the field.

I do not know if it is a better way.

```java
@RequiredArgsConstructor(onConstructor_ = @Lazy)
public class DeletedDateEntityListener {

    private final JdbcTemplate jdbcTemplate;

    @PreRemove
    void preRemove(final Object object) {
        if (object instanceof final AbstractEntity entity) {
            final var entityClass = entity.getClass();
            final var allSuperclasses = ClassUtils.getAllSuperclasses(entityClass);
            final var firstEntityClass = Stream.concat(allSuperclasses.stream(), Stream.of(entityClass))
                .filter(c -> c.getAnnotation(Entity.class) != null)
                .findFirst()
                .orElseThrow();
            final var annotation = firstEntityClass.getAnnotation(Table.class);
            final String tableName;
            if (annotation != null) {
                tableName = annotation.name();
            } else {
                tableName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, firstEntityClass.getSimpleName());
            }
            jdbcTemplate.execute(
                "UPDATE %s SET deleted_date=UTC_TIMESTAMP() WHERE id=%d".formatted(tableName, entity.getId()));
        }
    }

}

```
