How to fill an ArrayList of ArrayLists with a Left Join?
A standard way to do this is through break-processing, where you track one value, and when it changes, you do something special.... but you may find it easier to do a more unstructured system:

Map&lt;Integer, List&lt;Project&gt;&gt; employeeProjects = new HashMap&lt;&gt;();
Map&lt;Integer, Employee&gt; employees = new TreeMap&lt;&gt;(); // Treeset ... sorted by employeeID

// join the tables.
String select = " select e.employee_id, e.employee_name, p.project_id, p.project_name "
              + " from employees e
                      left outer join projects p on e.employee_id = p.employee_id"
              + " order by e.employee_id, p.project_name";

// do the select.....

while (rs.next()) {
    Integer employeeID = rs.get("employee_id");
    Employee emp = employees.get(employeeID);
    if (emp == null) {
        emp = new Employee();
        emp.setName(rs.get("employee_name");
        emp.setEmployeeID(employeeID);
        employees.put(employeeID, emp);
        // create a new list for this employee
        employeeProject.put(employeeID, new ArrayList&lt;Project&gt;());
    }

    String projectName = rs.getString("project_name");

    if (!rs.wasNull()) {
        List&lt;Project&gt; projects = employeeProject.get(employeeID);
        Project proj = new Project();
        proj.setID(rs.getInt("project_id"));
        proj.setName(projectName);
        projects.add(proj);
    }

}
rs.close();


Then, once you have the data structured the way you want, you can:

List&lt;Employee&gt; result = new ArrayList&lt;&gt;();
for (Employee emp : employees.values()) {
    emp.setProjects(employeeProjects.get(emp.getEmployeeID());
    result.add(emp);
}
return result;