JPA + Hibernate - @OneToMany with @Filter

By Arvind Rai, July 26, 2023
On this page we will learn to use @OneToMany with @Filter annotation in our Hibernate application.
1. The @OneToMany is a JPA annotation that specifies a one-to-many relation.
jakarta.persistence.OneToMany 
2. The @Filter is a Hibernate annotation that filters out entities or collections.
org.hibernate.annotations.Filter 
3. The @Filter can be used at class level as well as property level.
4. When we use @OneToMany with @Filter annotation, the data is filtered out for the given condition.

@OneToMany

The @OneToMany is a JPA annotation that specifies a many-valued association with one-to-many multiplicity. The @OneToMany has following optional elements.
cascade : Specifies operations that must be cascaded to the target of association.
fetch : Whether the association should lazily loaded or eagerly.
mappedBy : Specifies the field that owns relationship.
targetEntity : Specifies the entity class that is the target of the association.

Find the code snippet to use @OneToMany annotation.
@Entity
@Table(name = "employee")
public class Employee {
     ------
	@OneToMany(cascade=CascadeType.ALL)
	@JoinColumn(name="empid")
	private Set<Address> allAddress;
} 
Here empid is address table column that has foreign key relation with employee table.

@Filter

The @Filter is a Hibernate annotation that is used to filter out entities or collections using custom SQL criteria. We can parameterize the filter clause at runtime. Find the code snippet to use @Filter annotation.
@Entity
@Table(name = "employee")
@FilterDef(name="empFilter", parameters={
		@ParamDef( name="empCity", type=String.class),
})
public class Employee {
	---------
	@OneToMany(cascade=CascadeType.ALL)
	@JoinColumn(name="empid")
	@Filters( {
	    @Filter(name="empFilter", condition="city=:empCity"),
	} )
	private Set<Address> allAddress;
} 
Find the code snippet to set values to @Filter parameters.
Filter filter = session.enableFilter("empFilter");
filter.setParameter("empCity", "Lucknow"); 

Complete Example

In our example, we have employee table and address table. For an employee, there are more than one addresses. We need to fetch the employee details for the given employee id and its addresses for the given city name.
We will create one-to-many relation between employee and address entities using @OneToMany annotation and filter our addresses for the given city using @Filter annotation.
Now find the complete example.
MySQL Tables
CREATE TABLE `Employee` (
  `emp_id` int NOT NULL,
  `emp_name` varchar(45) DEFAULT NULL,
  `emp_age` int DEFAULT NULL,
  PRIMARY KEY (`emp_id`)
)
CREATE TABLE `Address` (
  `add_id` int NOT NULL,
  `empid` int DEFAULT NULL,
  `village` varchar(45) DEFAULT NULL,
  `city` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`add_id`)
)
 
Find the print screen of table data.
JPA + Hibernate - @OneToMany with @Filter
Find the Java code.
Employee.java
@Entity
@Table(name = "employee")
@FilterDef(name="empFilter", parameters={
		@ParamDef( name="empCity", type=String.class),
})
public class Employee {
	@Id
	@Column(name = "emp_id")
	private int empId;
	
	@Column(name = "emp_name")
	private String empName;
	
	@Column(name = "emp_age")
	private int empAge;
	
	@OneToMany(cascade=CascadeType.ALL)
	@JoinColumn(name="empid")
	@Filters( {
	    @Filter(name="empFilter", condition="city=:empCity"),
	} )
	private Set<Address> allAddress;
	---------
} 
Address.java
@Entity
@Table(name = "address")
public class Address {
	@Id
	@Column(name = "add_id")
	private int id;
	@Column(name = "empid")
	private int empId;
	@Column(name = "village")
	private String village;
	@Column(name = "city")
	private String city;
	---------
 
Main.java
public class Main {
  public static void main(String[] args) {
		CriteriaBuilder builder = HibernateUtil.getCriteriaBuilder();
		EntityManager em = HibernateUtil.getEntityManager();		
		CriteriaQuery<Employee> criteriaQuery = builder.createQuery(Employee.class);
		Root<Employee> empRoot = criteriaQuery.from(Employee.class);
		criteriaQuery.select(empRoot);
		criteriaQuery.where(builder.equal(empRoot.get("empId"), 1));
		org.hibernate.Session session = em.unwrap(org.hibernate.Session.class);
		Filter filter = session.enableFilter("empFilter");
		filter.setParameter("empCity", "Lucknow"); 
		List<Employee> emps = em.createQuery(criteriaQuery).getResultList();
		emps.forEach(e -> {
			  System.out.println(e);
			  System.out.println("--- Address ---");
			  e.getAllAddress().forEach(add -> {
				 System.out.println(add);
			  });
		} );
  }
} 
Output
1 - Narendra - 35
--- Address ---
1 - Siswa - Lucknow
2 - Anai - Lucknow 

Reference

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us