때때로 루트 엔티티는 연관 엔티티 컬렉션의 카운트를 제공해야 하는 경우가 있는데 여기서 성능 문제가 발생할 수 있다.

부서 목록을 보여주는 화면

부서 목록과 함께 직원 수와 프로젝트 수를 보여주는 화면이 있다.

엔티티

@Entity
public class Department {
  @Id
  @GeneratedValue
  private Long id;
  private String name;
  @OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
  private List<Employee> employees = new ArrayList<>();
  @OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
  private List<Project> projects = new ArrayList<>();
  // ...
}
@Entity
public class Employee {
  @Id
  @GeneratedValue
  private Long id;
  private String name;
  @ManyToOne
  @JoinColumn(name = "dept_id", referencedColumnName = "id")
  private Department department;
  // ...
}
@Entity
public class Project {
  @Id
  @GeneratedValue
  private Long id;
  private String name;
  @ManyToOne
  @JoinColumn(name = "dept_id", referencedColumnName = "id")
  private Department department;
  // ...
}

먼저 부서 목록을 조회 해보자

EntityManager em = emf.createEntityManager();
List<Department> departments = em.createQuery("select d from Department as d", Department.class).getResultList();

이제 부서의 직원 수와 프로젝트 수를 구해야 한다. 쉬운 선택은 Department 객체의 엔티티 컬렉션의 .size() 를 호출하는 것이다.

@Entity
public class Department {
  // ...
  @OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
  private List<Employee> employees = new ArrayList<>();
  @OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
  private List<Project> projects = new ArrayList<>();
  public int getCountOfEmployees() {
    return this.employees.size();
  }
  public int getCountOfProjects() {
    return this.projects.size();
  }
}

코드는 잘 동작한다.

List<Department> departments = 
   em.createQuery("select d from Department as d", Department.class).getResultList();
departments.forEach(department -> {
    System.out.println("Department : " + department.getName());
    System.out.println("CountOfEmployees : " + department.getCountOfEmployees() + "," + 
                       "CountOfProjects : " + department.getCountOfProjects());
});