java 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
}
然而,结果是一样的。为什么Employees
的Set
没有被创建。为了使它工作,必须改变什么
# 1 楼答案
在构造函数中或通过为字段指定初始值,自己初始化集合
实际上,当您从数据库获取对象时,Hibernate会将集合初始化为空集合。但是,当您自己创建对象并将其持久化时,Hibernate不会真正触及您创建的对象,只会持久化它,因此在这种情况下,它不会为您初始化字段
如果你想确保这个字段永远不为空,我同意这是可取的,你只需要自己确保它,甚至在坚持之前
# 2 楼答案
让我们仔细看看你的代码:
您已经创建了
Department
,三个Employees
,为每个Employee
设置对该Department
的引用,并将它们持久化Set
emps
将为空,因为在将员工持久化到数据库后,您没有重新加载department
。如果您这样更改代码:你应该没事的
我想提到的另一点是},这意味着
Department
和Employees
之间的关系是mappedBy
{Department
是主实体,它的Employee
是“从实体”,或者,如果你愿意,它承担维护映射和引用的所有责任。但是,在我上面评论的代码中,您将这个映射责任放在了Employee
实体上。您可能希望以这种方式更改代码:为了让
Department
完成维护映射和引用的工作