如何通过值对象StayId实现RoomOccupancy到Stay的多对一XML映射
解决方案
前提说明
需要先为值对象StayId配置Hibernate值类型映射,二选一即可:
- 若
StayId为可嵌入值对象,使用<component>标签映射 - 实现
UserType接口自定义StayId的持久化逻辑
Step1:配置Stay实体映射
核心是为Stay的stayId属性配置唯一约束,满足非主键关联的唯一性要求:
<class name="com.yourpackage.Stay" table="t_stay"> <id name="id" column="id"> <generator class="native"/> </id> <!-- 映射StayId值对象,以下示例假设StayId内部只有一个value属性,可根据实际字段调整 --> <component name="stayId" class="com.yourpackage.StayId" unique="true"> <property name="value" column="stay_id" not-null="true"/> </component> <!-- 其他Stay属性的映射 --> </class>
Step2:配置RoomOccupancy实体映射
分两种场景适配:
场景1:RoomOccupancy仅保留Stay关联属性,无独立stayId属性
直接通过property-ref指定关联Stay的stayId属性即可:
<class name="com.yourpackage.RoomOccupancy" table="t_room_occupancy"> <id name="id" column="id"> <generator class="native"/> </id> <property name="startDate" column="start_date" not-null="true"/> <property name="endDate" column="end_date" not-null="true"/> <!-- 多对一关联Stay,关联键对应Stay的stayId属性 --> <many-to-one name="stay" class="com.yourpackage.Stay" property-ref="stayId" not-null="true"> <column name="stay_id"/> </many-to-one> </class>
场景2:RoomOccupancy同时保留stayId属性和Stay关联属性
需要为多对一配置insert="false" update="false",避免字段重复映射冲突:
<class name="com.yourpackage.RoomOccupancy" table="t_room_occupancy"> <id name="id" column="id"> <generator class="native"/> </id> <property name="startDate" column="start_date" not-null="true"/> <property name="endDate" column="end_date" not-null="true"/> <!-- 映射自身的StayId值对象 --> <component name="stayId" class="com.yourpackage.StayId"> <property name="value" column="stay_id" not-null="true"/> </component> <!-- 多对一关联Stay,关闭读写权限避免和stayId属性冲突 --> <many-to-one name="stay" class="com.yourpackage.Stay" property-ref="stayId" insert="false" update="false"> <column name="stay_id"/> </many-to-one> </class>
注意事项
many-to-one标签下的列配置必须和Stay中stayId映射的数据库列完全匹配,字段数量、顺序、类型需一致,若StayId包含多个属性则对应配置多个<column>标签- 必须为
Stay的stayId字段添加唯一约束,否则Hibernate会抛出关联不唯一异常 - 所有包名需替换为你项目中对应类的实际包路径
内容的提问来源于stack exchange,提问作者user8088197
相关产品推荐
相关产品推荐

