Коллекция приложений OneToMany пуста в приложении Hibernate

Я разрабатываю простой Hibernate приложение для проверки OneToMany ассоциация. Сущности, которые я использую Employee а также Department который имеет много Employees:

@Entity
public class Department {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long departmentId;

    @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER, mappedBy="department")
    private Set<Employee> employees;

...
getters/setters

}

@Entity
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long employeeId;

    @ManyToOne
    @JoinColumn(name="employee_fk")
    private Department department;

...
getters/setters

}

Я создаю несколько записей с:

tx.begin();

        Department department = new Department();
        department.setDepartmentName("Sales");
        session.persist(department);

        Employee emp1 = new Employee("Ar", "Mu", "111");
        Employee emp2 = new Employee("Tony", "Almeida", "222");
        Employee emp3 = new Employee("Va", "Ka", "333");

        emp1.setDepartment(department);
        emp2.setDepartment(department);
        emp3.setDepartment(department);


        session.persist(emp1);
        session.persist(emp2);
        session.persist(emp3);

        Set<Employee> emps = department.getEmployees();
        emps.remove(emp2);

Однако в последней строке: emps.remove(emp2); Я получаю NullPointerException, emps Коллекция именно null, Я попытался изменить владельца ассоциации с:

 @Entity
    public class Department {

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long departmentId;

        @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER)
        @JoinColumn(name="department_fk")
        private Set<Employee> employees;

    ...
    getters/setters

    }

    @Entity
    public class Employee {

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long employeeId;

        @ManyToOne
        @JoinColumn(name="department_fk", insertable=false, updatable=false)
        private Department department;

    ...
    getters/setters

    }

Однако результат тот же. Почему Set из Employees не создан. Что нужно изменить, чтобы оно заработало?

2 ответа

Решение

Инициализируйте коллекцию самостоятельно, либо в конструкторе, либо указав начальное значение для поля.

Действительно, Hibernate инициализирует коллекцию пустой коллекцией, когда вы извлекаете объект из базы данных. Однако, когда вы создаете объект самостоятельно и сохраняете его, Hibernate не будет касаться созданного вами объекта, а только сохранит его, поэтому в этом случае он не будет инициализировать поле для вас.

Если вы хотите убедиться, что поле никогда не будет нулевым, что, я согласен, желательно, просто убедитесь в этом сами, даже до того, как сохранитесь.

Давайте внимательно посмотрим на ваш код:

Department department = new Department();
department.setDepartmentName("Sales");
session.persist(department);

Employee emp1 = new Employee("Ar", "Mu", "111");
Employee emp2 = new Employee("Tony", "Almeida", "222");
Employee emp3 = new Employee("Va", "Ka", "333");

emp1.setDepartment(department);
emp2.setDepartment(department);
emp3.setDepartment(department);


session.persist(emp1);
session.persist(emp2);
session.persist(emp3);

Set<Employee> emps = department.getEmployees();

Вы создали Department, три Employees, установите ссылку на это Department для каждого Employee и сохранил их.

Задавать emps будет нулевым, потому что после того, как вы сохранили сотрудников в базе данных, вы не перезагрузили department, Если вы измените код следующим образом:

....
session.persist(emp3);
department = session.get(Department.class, department.getDepartmentId());

Set<Employee> emps = department.getEmployees();
emps.remove(emp2);

Вы должны быть в порядке.

Еще один момент, который я хотел бы упомянуть, - ваше отношение между Department а также Employees являются mappedByDepartmentчто буквально означает, что Department скажем, "мастер" сущность и ее Employee являются "рабами", или, если вы предпочитаете, Department берет на себя все обязанности по ведению карт и ссылок. Но в своем коде, который я прокомментировал выше, вы возлагаете эту ответственность за отображение Employee юридические лица. Вы можете изменить свой код таким образом:

department.add(emp1);
department.add(emp2);
department.add(emp2);

session.persist(department);

чтобы сделать Department делать свою работу по поддержанию карт и ссылок.

Другие вопросы по тегам