JPA: How to apply Row Level Filter


Recently we got requirement to build an application where row level filter is required. example: Application provides service to different clients and we have to separate data for each client so no client can access other clients data.

Tech Stack

  • Spring
  • JPA/Hibernate
  • Any Database

Add common field to every Entity

To distinguish data clientwise we have decided to add clientId to each and every table using simple inheritance with @MappedSuperClass annotation.

Class abstract AbstractEntity{

        @Column(name = “client_id”)
        private long clientId;
        // getter and setter

        public void prePersist() {
                this.clientId = // Get the client id, mainly use static SecurityContextHolder.getContext().getAuthentication() methods to fetch client which you have stored with token for example.

Once you extend this entity to any other entity orm will create a clientId column.
And @PrePersist will add clientId automatically before saving this entity.

Solution using @Where

You can add this annotation on any entity, orm will add append your condition with where clause.

@Where(clause = "clientId=1")
Class Employee extends AbstractEntity{


Condition clientId=1 will be appended to every fetch made on entity Employee.


@Where accept constant value always, you can’t change the condition dynamically. Here we have used clientId=1 which is of no use as we hard coded clientId 1 always.

Solution using @Filter

With the user @Filter we can

  • Change value of condition dynamically, i.e. we can set clientId runtime.
  • We can enable/disable filter runtime.
        name = "clientFilter",
        parameters = @ParamDef(name = "clientId", type = "long")
        name = "clientFilter",
        condition = "clientId = :clientId"
Class Employee extends AbstractEntity{


Here we have applied this filter on class so ORM will look if filter applied on entity is enabled or not, if enable than it will append where on every fetch.

Enable filter runtime

We can enable/disable filter using EntityManager, you need to unwrap session and set the parameter.

private EntityManager entityManager;

Session session = entityManager.unwrap(Session.class);
Filter filter = session.enableFilter("clientFilter");
filter.setParameter("clientId", clientId);

This will enable clientFilter and set a clientId dynamically. Better to create separate class and method to perform this operation.

Please contact us if you have any doubt.

Share current post by copy:
Happy Learning!

Yogesh P