Hibernate @Filter and @FilterJoinTable Annotation Example

By Arvind Rai, February 21, 2015
In this page we will learn in detail how to use hibernate @Filter and @FilterJoinTable annotation. Filtering in hibernate is like creating a view in database. We need to create filter definition using @FilterDef annotation where we define a name and parameters. Using this filter definition name, we enable filter by Session enableFilter() method and disable it by disableFilter() method. To apply filter on entity load we use @Filter and on collection load we need to use @FilterJoinTable on association. Hibernate filter is created and used by below annotations and methods.

@FilterDef: Defines filter definition name and parameters to set values while enabling filter.
@Filter: Adds filter to an entity or a target entity.
@Filters: To define more than one @Filter, use @Filters.
@FilterJoinTable: Use it to filter join table.
Session.enableFilter(): Finally filter is enabled using this method. We need to pass filter definition name.
Session.disableFilter(): Pass filter definition name to disable filter.
deduceAliasInjectionPoints: This is the attribute of @Filter annotation which has Boolean value that controls explicit aliasing.

Database Structure Used in Demo

Find the database being used in the example.
Hibernate @Filter and @FilterJoinTable Annotation Example

Using @FilterDef, @Filters and @Filter to Load Entity

To filter entity load in hibernate, start with @FilterDef. Using this annotation we define filter definition name and parameter definition as below.
@Entity
@Table(name="student") 
@FilterDef(name="studentFilter", parameters={
		@ParamDef( name="maxAge", type="integer" ),
		@ParamDef( name="minAge", type="integer" ),
		@ParamDef( name="minNumber", type="integer")
})
@Filters( {
    @Filter(name="studentFilter", condition=":minAge <= age and :maxAge >= age"),
    @Filter(name="studentFilter", condition=":minNumber <= number")
} )
public class Student {} 
After filter definition, use filter definition name to define @Filter annotation. The condition attribute workd as where clause. There are two types of variable in query with semicolon and without semicolon.
Variable with Semicolon(:) : Variable with semicolon(:) are set values at the time of enabling filter.
Variable without Semicolon(:) : These are the attributes of entity.

Find the entity for the filter example.
Student.java
package com.concretepage;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.Filters;
import org.hibernate.annotations.ParamDef;
@Entity
@Table(name="student")
@FilterDef(name="studentFilter", parameters={
		@ParamDef( name="maxAge", type="integer" ),
		@ParamDef( name="minAge", type="integer" ),
		@ParamDef( name="minNumber", type="integer")
})
@Filters( {
    @Filter(name="studentFilter", condition=":minAge <= age and :maxAge >= age"),
    @Filter(name="studentFilter", condition=":minNumber <= number")
} )
public class Student {
	@Id
	@Column(name="id")
	private Integer id;
	@Column(name="age")
	private Integer age;
	@Column(name="name")
	private String name;
	@Column(name="number")
	private Integer number;
	public Student(){}
	public Student(Integer id, Integer age, String name, Integer number){
		this.id = id;
		this.age = age;
		this.name = name;
		this.number = number;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getNumber() {
		return number;
	}
	public void setNumber(Integer number) {
		this.number = number;
	}
} 

Use Session enableFilter() and disableFilter()

While using filter, we need to use session method as Session.enableFilter() passing filter definition name. It returns org.hibernate.Filter instance. To set parameter values, filter provides setParameter() method. Finally if we want to disable filter, we just use Session.disableFilter() passing filter definition name.
Filter filter = session.enableFilter("studentFilter");
filter.setParameter("maxAge", new Integer(24));
filter.setParameter("minAge", new Integer(22));
filter.setParameter("minNumber", new Integer(39)); 
------------------------------------------------
------------------------------------------------
session.disableFilter("studentFilter");
Find the main class to enable and disable filter.
FilterDemo.java
package com.concretepage;
import java.util.List;
import org.hibernate.Filter;
import org.hibernate.Session;
public class FilterDemo {
	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		System.out.println("--Enable Filter--");
		Filter filter = session.enableFilter("studentFilter");
		filter.setParameter("maxAge", new Integer(24));
		filter.setParameter("minAge", new Integer(22));
		filter.setParameter("minNumber", new Integer(39));
		session.beginTransaction();
		List<Student> results = session.createQuery("from Student").list();
		for(Student s: results){
			System.out.println("Name:"+s.getName()+", Age:"+s.getAge()+", Number:"+s.getNumber());
		}
		System.out.println("--Apply where clause--");
		results = session.createQuery("from Student where id > 2").list();
		for(Student s: results){
			System.out.println("Name:"+s.getName()+", Age:"+s.getAge()+", Number:"+s.getNumber());
		}
		System.out.println("--Disable Filter--");
		session.disableFilter("studentFilter");
		results = session.createQuery("from Student").list();
		for(Student s: results){
			System.out.println("Name:"+s.getName()+", Age:"+s.getAge()+", Number:"+s.getNumber());
		}
     	        session.close();
	}
} 
Find the output.
--Enable Filter--
Hibernate: select student0_.id as id1_3_, student0_.age as age2_3_, student0_.name as name3_3_, student0_.number as number4_3_ from student student0_ where ? <= student0_.age and ? >= student0_.age and ? <= student0_.number
Name:Shyam, Age:24, Number:41
Name:Mahesh, Age:22, Number:39
--Apply where clause--
Hibernate: select student0_.id as id1_3_, student0_.age as age2_3_, student0_.name as name3_3_, student0_.number as number4_3_ from student student0_ where ? <= student0_.age and ? >= student0_.age and ? <= student0_.number and student0_.id>2
Name:Mahesh, Age:22, Number:39
--Disable Filter--
Hibernate: select student0_.id as id1_3_, student0_.age as age2_3_, student0_.name as name3_3_, student0_.number as number4_3_ from student student0_
Name:Ram, Age:25, Number:40
Name:Shyam, Age:24, Number:41
Name:Mahesh, Age:22, Number:39
Name:Rahim, Age:23, Number:38 

Using @FilterDef and @FilterJoinTable to Load Collection

To filter collection load in hibernate association, we need to use @FilterJoinTable annotation. This annotation is applied at association level within entity.
@Entity
@Table(name="company") 
@FilterDef(name="empMaxId", parameters={
		@ParamDef( name="maxId", type="integer" )
})
public class Company {
---------------------------------
---------------------------------
@OneToMany(cascade=CascadeType.ALL)
@JoinTable(name="Company_Employee", joinColumns={@JoinColumn(name ="companyId")},
			inverseJoinColumns={@JoinColumn(name ="employeeId")})
@FilterJoinTable(name="empMaxId", condition=":maxId >= employeeId")
private Set<Employee> employees;
---------------------------------
---------------------------------
} 
@FilterJoinTable is used with @JoinTable. When entity is loaded, collection will be filtered according to @FilterJoinTable definition.
Filter filter = session.enableFilter("empMaxId");
filter.setParameter("maxId", new Integer(2)); 
Find the entity for the @FilterJoinTable example
Company.java
package com.concretepage;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.FilterJoinTable;
import org.hibernate.annotations.ParamDef;
@Entity
@Table(name="company")
@FilterDef(name="empMaxId", parameters={
		@ParamDef( name="maxId", type="integer" )
})
public class Company {
	@Id
	@Column(name="id")
	private Integer id;
	@Column(name="name")	
	private String name;
	@OneToMany(cascade=CascadeType.ALL)
	@JoinTable(name="Company_Employee", joinColumns={@JoinColumn(name ="companyId")},
			inverseJoinColumns={@JoinColumn(name ="employeeId")})
	@FilterJoinTable(name="empMaxId", condition=":maxId >= employeeId")
	private Set<Employee> employees;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Set<Employee> getEmployees() {
		return employees;
	}
	public void setEmployees(Set<Employee> employees) {
		this.employees = employees;
	}
} 
Find the association entity.
Employee.java
package com.concretepage;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="employee")
public class Employee {
	@Id
	@Column(name="id")
	private Integer id;
	@Column(name="name")	
	private String name;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
} 
Enable filter as below.
FilterJoinTableDemo.java
package com.concretepage;
import java.util.Set;
import org.hibernate.Filter;
import org.hibernate.Session;
public class FilterJoinTableDemo {
	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		System.out.println("--Enable Filter--");
		Filter filter = session.enableFilter("empMaxId");
		filter.setParameter("maxId", new Integer(2));
		session.beginTransaction();
		Company company = (Company) session.get(Company.class, new Integer(1));
		Set<Employee>  employees = company.getEmployees();
		for(Employee e: employees){
			System.out.println("Id:"+e.getId()+", Name:"+e.getName());
		}
     	        session.close();
	}
} 
Find the output.
--Enable Filter--
Hibernate: select company0_.id as id1_1_0_, company0_.name as name2_1_0_ from company company0_ where company0_.id=?
Hibernate: select employees0_.companyId as companyI1_1_0_, employees0_.employeeId as employee2_0_0_, employee1_.id as id1_2_1_, employee1_.name as name2_2_1_ from Company_Employee employees0_ inner join employee employee1_ on employees0_.employeeId=employee1_.id where ? >= employees0_.employeeId and employees0_.companyId=?
Id:2, Name:B
Id:1, Name:A

Disable deduceAliasInjectionPoints

deduceAliasInjectionPoints is a Boolean value that controls explicit aliasing. If we are using ANSI SQL reserved keyword as a column, then hibernate incorrectly aliases it. We can use it in our filter as below.
@Filters( {
    @Filter(name="studentFilter", condition=":minAge <= age and :maxAge >= age", deduceAliasInjectionPoints = false),
    @Filter(name="studentFilter", condition=":minNumber <= number", deduceAliasInjectionPoints = false)
} ) 
Now we are done. Happy Learning.

Download Complete Source Code and Database SQL File

POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us