一对多关系中,一端用集合属性(如Set)表示“拥有多个”,多端用单个引用变量(private Department department)体现“属于哪一个”;映射时与共用同一外键列但视角相反。

一对多场景下,变量引用和集合存储的核心在于:一端用单个对象引用表示“归属关系”,多端用集合类型属性(如 Set、List)承载多个关联实例。这不是语法技巧,而是对业务逻辑的自然建模。
一端定义集合属性,明确“拥有多个”的语义
比如部门(Department)与员工(Employee)的关系中,一个部门对应多名员工。这时 Department 类需声明集合字段:
- 推荐使用
Set——避免重复,符合业务直觉(同一员工不会在同一个部门出现两次) - 不直接用
HashSet实例化,而保留接口类型,便于 Hibernate 延迟加载代理注入 - 必须提供 getter/setter,且 setter 通常设为 protected 或 package-private,防止外部误清空集合
多端维护外键引用,体现“属于哪一个”的指向
Employee 类不存多个部门,只存一个所属部门的引用:
- 声明
private Department department;,这是典型的单向引用变量 - 该字段映射到数据库 employee 表中的
depart_id外键列 - 即使不做双向关联,仅靠这一引用也足以完成“查员工→知部门”操作
映射配置中, 和 各司其职
XML 映射里,两端配置不可互换:
- Department.hbm.xml 中的
告诉 Hibernate:“emps 这个集合,数据来自 employee 表,靠 depart_id 字段关联” - Employee.hbm.xml 中的
告诉 Hibernate:“department 这个对象,主键值从 employee 表的 depart_id 列查出来” - 二者共用同一外键列(
depart_id),但视角相反:一端“向外发散”,多端“向内指向”
实际操作时,集合的初始化与变更需谨慎
直接操作集合可能引发持久化异常或脏数据:
- 新建 Department 时,建议初始化空集合:
private Setemps = new HashSet(); - 添加员工应调用
department.getEmps().add(emp),而非emp.setDepartment(department)单边设置(若未配置双向同步) - 删除员工时,优先从集合中移除并级联处理,而不是仅删 employee 记录——否则部门集合里仍残留已失效引用










