Hibernate JPA @BatchSize annotation Example
@BatchSize
The @BatchSize annotation is used to specify the size for batch loading the entries of a lazy collection.BatchSize Defines size for batch loading of collections or lazy entities. For example...
@Entity
@BatchSize(size=100)
class Product {
...
}
will initialize up to 100 lazy Product entity proxies at a time.
@OneToMany
@BatchSize(size = 5) /
Set getProducts() { ... };
will initialize up to 5 lazy collections of products at a time.
Hibernate offers the @BatchSize annotation, which can be used when fetching uninitialized entity proxies.
Considering the following entity mapping:
@BatchSize mapping example
@Entity(name = "Department")
public static class Department {
@Id
private Long id;
@OneToMany(mappedBy = "department")
//@BatchSize(size = 5)
private List<Employee> employees = new ArrayList<>();
//Getters and setters omitted for brevity
}
@Entity(name = "Employee")
public static class Employee {
@Id
private Long id;
@NaturalId
private String name;
@ManyToOne(fetch = FetchType.LAZY)
private Department department;
//Getters and setters omitted for brevity
}
Considering that we have previously fetched several Department entities, and now we need to initialize the employees entity collection for each particular Department, the @BatchSize annotations allows us to load multiple Employee entities in a single database roundtrip.
@BatchSize fetching example
List<Department> departments = entityManager.createQuery("select d " +
"from Department d " +
"inner join d.employees e " +
"where e.name like 'John%'", Department.class)
.getResultList();
for ( Department department : departments ) {
log.infof(
"Department %d has {} employees",
department.getId(),
department.getEmployees().size()
);
}
Without @BatchSize, you’d run into a N+1 query issue, so, instead of 2 SQL statements, there would be 10 queries needed for fetching the Employee child entities.
However, although @BatchSize is better than running into an N+1 query issue, most of the time, a DTO projection or a JOIN FETCH is a much better alternative since it allows you to fetch all the required data with a single query.
Comments
Post a Comment