4

I successfully implemented a soft delete (aka delete flag) for the entities of my applications. However, I have one remaining problem. I've written a custom JPARepository with findAll and count methods that filter out the deleted ones. I do this with the specification:

softDeleteSpecification = new Specification<T>() {
        @Override
        public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            return cb.or(cb.isNull(root.get(DELETED_FIELD_NAME)), cb.equal(root.<T>get(DELETED_FIELD_NAME), false));
        }
    };

If the entity has for example a OneToMany child list of entities that are also soft deleted, this list is not filtered because the query is not run by its repository.

My question: Can I modify the specification above so that children that are soft deleted are filtered out? An alternative would be filtering the childs with reflection (manually after the query), but that wouldn't be performant.

Arthur C
  • 1,274
  • 1
  • 14
  • 34

2 Answers2

0

With Hibernate, you can use @Whereannotation on your entities

@Entity
@Where(clause = "deleted = 0")
public class MyEntity {
...

That said, take a look at @SQLDelete for an alternative to your implementation of soft delete.

Predrag Maric
  • 23,938
  • 5
  • 52
  • 68
  • We've tried that. The extra where clause is added to queries performed on the entity itself, queries performed on parents with eager fetching, but not queries with lazy fetching. On a side note: we're trying to avoid Hybernate-specific commands, because we don't want any direct dependency. That's why I built a custom soft delete solution instead of using the where clause. The where clause is good idea though. – Arthur C Jan 21 '15 at 12:24
0

I got this working. In case where each product have one child entity category i.e. Category is child entity to Product, below code worked for me

public static Specification<Product> whereCategoryNameEquals(@NonNull String categoryName)  {
    return (Root<Product> root, CriteriaQuery<?> query, CriteriaBuilder cb) 
        -> cb.equal(root.get(Product_.CATEGORY).get(Category_.CATEGORY_NAME),categoryName);
}
Miss Chanandler Bong
  • 4,081
  • 10
  • 26
  • 36
Sridhar Patnaik
  • 970
  • 1
  • 13
  • 24