Domanda

I am developing a simple Hibernate application to test an OneToMany association. The Entities I use are Employee and Department which has many 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

}

I create some records with:

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);

However in the last line: emps.remove(emp2); I receive a NullPointerException, the emps Collection is namely null. I have tried to change the owner of the association with:

 @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

    }

However the result the same. Why is the Set of Employees not created. What must be changed in order to make it work?

È stato utile?

Soluzione

Initialize the collection yourself, either in the constructor or by specifying an initial value for the field.

Indeed Hibernate will initialize the collection to an empty collection when you fetch the object from the database. However, when you create the object yourself and persist it, Hibernate will not really touch the object you created, only persist it, so it won't initialize the field for you in that case.

If you want to make sure the field is never null, which I agree is desirable, simply make sure of it yourself, even before persisting.

Altri suggerimenti

Let's take a close look at your code:

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();

You have created Department, three Employees, set reference to that Department for each Employee and persisted them.

Set emps will be null because after you persisted employees to database, you didn't reload department. If you change code like this:

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

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

You should be fine.

Another point I'd like to mention - your relation between Department and Employees are mappedBy Department, which literally means that Department is let's say "master" entity and its Employee are "slave", or, if you prefer, Department takes all responsibilities on maintaining mapping and references. But, in your code I commented above, you put this mapping responsibility on Employee entities. You may want to change your code that way:

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

session.persist(department);

in order to make Department do its job of maintaining mapping and references.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top