Как сопоставить столбец сотрудника - manager, как экземпляр сотрудника

Я должен выполнить перемещение курсора, чтобы получить все экземпляры Employee. Считать набор результатов полностью прокручиваемым (назад и вперед, начало, конец и т.д.). Если у сотрудника есть менеджер, он также должен содержать его как экземпляр сотрудника. Это таблица Employee с несколькими столбцами.

ID         INTEGER PRIMARY KEY,
FIRSTNAME  VARCHAR(10),
LASTNAME   VARCHAR(10),
MIDDLENAME VARCHAR(10),
POSITION   VARCHAR(9),
MANAGER    INTEGER,
HIREDATE   DATE,
SALARY     DOUBLE,
DEPARTMENT INTEGER,
CONSTRAINT FK_DEPTNO FOREIGN KEY (DEPARTMENT) REFERENCES DEPARTMENT (ID)

Например, если вставить в таблицу:

INSERT INTO EMPLOYEE VALUES (7654, 'JOHN', 'MARTIN', 'MARIA', 'SALESMAN', 7698, TO_DATE('28-9-1981', 'DD-MM-YYYY'), 1250, 30);
        
INSERT INTO EMPLOYEE VALUES (7698, 'JOHN', 'BLAKE', 'MARIA', 'MANAGER', 7839, TO_DATE('1-5-1981', 'DD-MM-YYYY'), 2850, 30);

ID менеджера у первого сотрудника является 7698.

Когда метод возвращает список то вместо ID менеджера необходимо вывести всю информацию о менеджере. В результате результат должен возвращаться как:

[Employee{id=7654, fullName=FullName{firstName=JOHN, lastName=MARTIN, middleName=MARIA}, position=SALESMAN, hired=1981-09-28, salary=1250.00000, manager=Employee{id=7698, fullName=FullName{firstName=JOHN, lastName=BLAKE, middleName=MARIA}, position=MANAGER, hired=1981-05-01, salary=2850.00000, manager=null}}

Я создал две Map<Integer, Employee>: manag and employ, в них отправил данные про менеджеров и про других подчиненных, но что дальше делать, не знаю.

Может кто-то подсказать, как решить проблему или есть ли другой способ решение задачи?

Map<Integer, Employee> manag = new HashMap<>();
Map<Integer, Employee> employ = new HashMap<>();
                
BigInteger id = BigInteger.valueOf(resultSet.getInt("id"));
FullName fullname = new FullName(
    resultSet.getString("firstName"), 
    resultSet.getString("lastName"), 
    resultSet.getString("middleName")
);
Position position = Position.valueOf(resultSet.getString("position"));
LocalDate hired = resultSet.getObject("hiredate", LocalDate.class);
BigDecimal salary = BigDecimal.valueOf(resultSet.getInt("salary"));
Employee manager = null;//String.valueOf(resultSet.getInt("manager")) !=null? new Employee(id, fullname, position, hired, salary, null) : null;

if (resultSet.getString("position").equalsIgnoreCase("manager")) {
    Integer key = resultSet.getInt("id");
    Employee value = new Employee(id, fullname, position, hired, salary, null);
    manag.put(key, value);
} else {
    Integer key = resultSet.getInt("id");
    Employee value = new Employee(id, fullname, position, hired, salary, null);
    employ.put(key, value);
}

Это класс Employee, тут нельзя делать изменения.

public class Employee {
    private final BigInteger id;
    private final FullName fullName;
    private final Position position;
    private final LocalDate hired;
    private final BigDecimal salary;
    private final Employee manager;

    @JsonCreator
    public Employee(@JsonProperty("id") final BigInteger id,
                    @JsonProperty("fullName") final FullName fullName,
                    @JsonProperty("position") final Position position,
                    @JsonProperty("hired") final LocalDate hired,
                    @JsonProperty("salary") final BigDecimal salary,
                    @JsonProperty("manager") final Employee manager) {
        this.id = id;
        this.fullName = fullName;
        this.position = position;
        this.hired = hired;
        this.salary = salary.setScale(5, RoundingMode.HALF_UP);
        this.manager = manager;
    }

    public BigInteger getId() {
        return id;
    }

    public FullName getFullName() {
        return fullName;
    }

    public Position getPosition() {
        return position;
    }

    public LocalDate getHired() {
        return hired;
    }

    public BigDecimal getSalary() {
        return salary;
    }

    public Employee getManager() {
        return manager;
    }

Ответы (2 шт):

Автор решения: Igor
class Employee {
  ...
  Employee(..., Integer managerId) {
    ...
    this.managerId = managerId;
  }
  Integer managerId;
  Employee manager;
}

Employee value = new Employee(id, fullname, position, hired, salary, resultSet.getInt("manager"));
employ.put(key, value);

employ.forEach((k,v) -> v.manager = employ.get(v.managerId));
→ Ссылка
Автор решения: Alex Rudenko

Поскольку в классе Employee поле manager определено как final, оно должно передаваться в конструктор.

Вероятно, имеет смысл вычитать иерархию по очереди:

  1. Вычитать из базы всех президента по условию: SELECT * FROM Employee WHERE position = 'president' OR manager IS NULL;, заполнить Employee president
Employee president;
  1. Вычитать из базы всех менеджеров по условию: SELECT * FROM Employee WHERE position = 'manager' AND manager = $president.id, заполнить мапу manag:
Integer  key = resultSet.getInt("id");
Employee manager = new Employee(id, fullname, position, hired, salary, president);
manag.put(key, manager);
  1. Вычитать всех остальных служащих: SELECT * FROM Employee WHERE position <> 'manager' AND manager IS NOT NULL; Заполнить их мапу, вычитывая менеджеров из мапы manag:
Integer  key = resultSet.getInt("id");
Employee employee = new Employee(id, fullname, position, hired, salary, manag.get(resultSet.getInt("manager"))));
employ.put(key, employee);
→ Ссылка