I need to implement JPA Soft Delete repository and support JPA auditing for several columns at the same time. For now, I've implemented Soft Delete repository via EL and @Query+@Modifying annotations:
@Override
@Modifying
@Query("update #{#entityName} e set e.active = false where e.id = ?1")
void deleteById(UUID id);
@Override
default void delete(T entity)
{
deleteById(entity.getId());
}
@Override
@Modifying
@Query("update #{#entityName} e set e.active = false where e.id in ?1")
void deleteAll(Iterable<? extends T> iterable);
@Override
@Modifying
@Query("update #{#entityName} e set e.active = false")
void deleteAll();
But with such implementation audit columns are not updated because if I correctly understand, @Query
annotation doesn't trigger any Lifecycle Callback methods.
@Where
annotation on the Entity level is not an option because there is the need to have a possibility to query soft deleted entities.
Could you please help with any other possible solutions?
UPDATE:
I've decided to go with the overridden default delete repository methods to update an active flag to 'false' and save an entity via common save()
method.
@Override
default void deleteById(UUID id)
{
Assert.notNull(id, "The given id must not be null!");
Optional<T> entity = this.findById(id);
entity.ifPresent(this::delete);
}
@Override
default void delete(T entity)
{
Assert.notNull(entity, "The entity must not be null!");
entity.setActive(Boolean.FALSE);
this.save(entity);
}
@Override
default void deleteAll(Iterable<? extends T> entities)
{
Assert.notNull(entities, "The given Iterable of entities must not be null!");
for (T entity : entities)
{
this.delete(entity);
}
}
@Override
default void deleteAll()
{
for (T element : this.findAll())
{
this.delete(element);
}
}