Получите коллекцию всего из одного поля из объекта, используя JPA или Hibernate - PullRequest
1 голос
/ 26 мая 2020

В настоящее время у меня есть приложение Spring Boot с отображенными объектами Hibernate. Один из них - это, скажем, Employee, и я хотел бы получить все имена пользователей сотрудников по отделам.

Что-то вроде SQL:

SELECT username FROM employee WHERE departmentId=1 AND active=true;

Класс сотрудника:

@Entity
public class Employee extends BaseEntity implements Serializable {
    private int id;
    private String name;
    private String username;
    private String building;
    private Integer departmentId;
    private Boolean active;
    ... other stuff about them ...
    ... annotated getters and setters ...
}

Я (верю, что) могу получить всех Сотрудников отдела с чем-то вроде:

public List<Employee> employeesInDepartment(Integer departmentId) {
    Session session = getSession();
    CriteriaBuilder builder = session.getCriteriaBuilder();
    CriteriaQuery<Employee> criteriaQuery = builder.createQuery(Employee.class);
    Root<Employee> root = criteriaQuery.from(Employee.class);
    criteriaQuery.where(builder.and(
            builder.equal(root.get("departmentId"), departmentId),
            builder.equal(root.get("active"), true)))
            .orderBy(builder.desc(root.get("timeCreated")))
            .select(root);
    return session.createQuery(criteriaQuery).list();
}

Но скажем, мне нужно только Set их имен пользователей или зданий, которые они in, то мне не нужно заполнять остальные 20+ полей о каждом сотруднике, и мне просто нужно вернуть набор из одного поля.

    return session.createQuery(criteriaQuery).stream()
                .map(Comment::getUsername).collect(Collectors.toSet());

Однако это тратит впустую передачу 20+ полей из хранилища БД и сети БД обратно в службу приложения, и кажется, что запрос, показанный вверху, будет правильным для представления в нотации объекта JPA. Тем не менее, я не уверен, что писать вместо этого; не было очевидного способа Hibernate для получения отфильтрованной коллекции сущностей, поэтому способ JPA казался правильным, но я нахожу документацию не такой простой для gr asp, как я надеялся. Я смотрю на что-то вроде:

public Set<String> usernamesOfEmployeesInDepartment(Integer departmentId) {
    Session session = getSession();
    CriteriaBuilder builder = session.getCriteriaBuilder();
    CriteriaQuery<Employee> criteriaQuery = builder.createQuery(Employee.class);
    Root<Employee> root = criteriaQuery.from(Employee.class);
    criteriaQuery.where(builder.and(
            builder.equal(root.get("departmentId"), departmentId),
            builder.equal(root.get("active"), true)))
            .orderBy(builder.desc(root.get("timeCreated")))
            .select(root).select(root.get("username"));
    return new HashSet<>(session.createQuery(criteriaQuery).list());
}

Это не дает мне правильного типа… И если я хочу получить отдельную коллекцию местоположений зданий сотрудников отдела, мне нужно добавить distinct тоже где-то есть, а где?

...