Hibernate Filters

Restrictions You Can Switch On and Off

A filter is a named, parameterised WHERE condition. It is off by default and you enable it per session. Use it when the condition depends on runtime data (the current region, the current seller) or must be optional.

import org.hibernate.annotations.*;

@Entity
@Table(name = "products")
@FilterDef(name = "regionFilter", parameters = @ParamDef(name = "region", type = String.class))
@Filter(name = "regionFilter", condition = "region = :region")
@FilterDef(name = "liveOnly")
@Filter(name = "liveOnly", condition = "deleted = false")
public class Product { ... }
@Transactional(readOnly = true)
public List<Product> productsFor(String region, boolean includeDeleted) {
    Session session = em.unwrap(Session.class);
    session.enableFilter("regionFilter").setParameter("region", region);
    if (!includeDeleted) session.enableFilter("liveOnly");
    return em.createQuery("select p from Product p", Product.class).getResultList();
}

Filter Rules

  • Filters apply to queries (JPQL, Criteria) and collection loading. They do not apply to find() / findById() by primary key, so check ownership yourself when loading by id.
  • They apply to the session, so enable them at the start of the transaction: a Spring HandlerInterceptor or an aspect on your services can do it for every request.
  • Native queries ignore them.

SQL Log

productsFor("SOUTH", false)

Example output

select p1_0.id,p1_0.name,p1_0.region from products p1_0
 where p1_0.region=? and p1_0.deleted = false