【问题标题】:OneToMany association collection is null in Hibernate application在 Hibernate 应用程序中,OneToMany 关联集合为空
【发布时间】:2014-04-27 13:14:46
【问题描述】:

我正在开发一个简单的Hibernate 应用程序来测试OneToMany 关联。我使用的实体是EmployeeDepartment,其中有很多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); 我收到一个NullPointerExceptionemps 集合就是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

    }

但是结果相同。为什么没有创建EmployeesSet。必须进行哪些更改才能使其正常工作?

【问题讨论】:

    标签: java hibernate nullpointerexception associate


    【解决方案1】:

    自己初始化集合,可以在构造函数中,也可以通过为字段指定初始值。

    确实,当您从数据库中获取对象时,Hibernate 会将集合初始化为空集合。但是,当您自己创建对象并将其持久化时,Hibernate 不会真正接触您创建的对象,只会持久化它,因此在这种情况下它不会为您初始化字段。

    如果您想确保该字段永远不会为空,我同意这是可取的,只需自己确保它,甚至在坚持之前。

    【讨论】:

    • 你说得对。问题仅仅是集合没有在实体中初始化!完成后它工作。我无法想象问题会出现在如此微不足道的一点上,我已经从资源中复制了实体,但我没有注意到这一点。
    【解决方案2】:

    让我们仔细看看你的代码:

    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,为每个Employee 设置了对Department 的引用并将它们持久化。

    设置emps 将为空,因为在将员工持久化到数据库后,您没有重新加载department。如果您像这样更改代码:

    ....
    session.persist(emp3);
    department = session.get(Department.class, department.getDepartmentId());
    
    Set<Employee> emps = department.getEmployees();
    emps.remove(emp2);
    

    你应该没事的。

    我想提的另一点 - DepartmentEmployees 之间的关系是 mappedBy Department,字面意思是 Department 是“主”实体,它的 Employee 是“奴隶”,或者,如果您愿意,Department 承担维护映射和引用的所有责任。但是,在我上面评论的代码中,您将此映射责任放在Employee 实体上。您可能希望以这种方式更改您的代码:

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

    为了让Department 完成维护映射和引用的工作。

    【讨论】:

      猜你喜欢
      • 2017-11-18
      • 2022-01-08
      • 2016-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-05
      • 2014-07-10
      • 1970-01-01
      相关资源
      最近更新 更多