JPQL Single-Point Association

Single-Point Association relationship like Many-To-One and One-To-One eager loads associated table. It causes N+1 Select Problem which will produce performance problem on the application. 1 Select from main query and N Selects for each associated table. N selects are unnecessary when data can be retrieved by a single select statement.

If there are thousands of records, the N+1 select statement could result to 1 Huge SELECT Statement

To fix it, change fetch type to laze

Or use left join fetch in the query to load associated objects eagerly
"select s from Student s left join fetch"

You can also use batch fetching to improve performance when querying related objects.

JPQL: Custom TypedQuery

//returns custom type 
public List<TourScheduleWithClientCount> searchByDateWithCount(Date from, Date to) {

    String sql = "SELECT NEW com.package.TourScheduleWithClientCount(ts,COUNT(ta.clientId)) FROM TourSchedule ts LEFT JOIN ts.tourAppliedList ta WHERE "
              + (to != null ? "ts.fromDate <= :to AND " : "")
              + (from != null ? "ts.fromDate >= :from AND " : "") 
              + " ts.dFlg = 0 GROUP BY ORDER BY ts.fromDate DESC";
    Query query = em.createQuery(sql);
    if (from != null) {
      query.setParameter("from", from);
    if (to != null) {
      query.setParameter("to", to);
    return query.getResultList();

public class TourScheduleWithClientCount {

    public TourScheduleWithClientCount() {

    public TourScheduleWithClientCount(TourSchedule tourSchedule, Long count) {
        this.schedule = tourSchedule;
        this.numberOfClients = count;

    private TourSchedule schedule;
    private Long numberOfClients;

    public TourSchedule getSchedule() {
        return schedule;

    public void setSchedule(TourSchedule schedule) {
        this.schedule = schedule;

    public Long getNumberOfClients() {
        return numberOfClients;

    public void setNumberOfClients(Long numberOfClients) {
        this.numberOfClients = numberOfClients;