Spring2+Hibernate3升级至Spring5+Hibernate5时遇IdClass映射异常
问题分析与解决方案
这个报错expecting IdClass mapping确实是复合主键(<composite-id>)的映射在Hibernate 5中不兼容旧写法导致的——Hibernate 5对复合主键的映射规则要求更严格,和Hibernate 3的宽松处理逻辑不同。结合你提供的配置和代码,以下是具体解决步骤:
1. 修正复合主键的hbm.xml映射
Hibernate 5要求使用<composite-id>时,必须满足以下两种规范之一:
方式一:使用独立主键类(IdClass)
- 创建独立的主键类,必须实现
Serializable,并正确重写equals()和hashCode()方法:
public class FileCompositeId implements Serializable { private int id1; private String id2; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; FileCompositeId that = (FileCompositeId) o; return id1 == that.id1 && Objects.equals(id2, that.id2); } @Override public int hashCode() { return Objects.hash(id1, id2); } // 对应getter、setter方法 }
- 修改对应的hbm.xml文件,显式指定
class属性指向主键类:
<class name="FileEntity" table="file_table" schema="schema1" catalog="demo"> <composite-id name="id" class="com.yourpackage.FileCompositeId"> <key-property name="id1" column="cl1"/> <key-property name="id2" column="cl2"/> </composite-id> <!-- 其他属性映射 --> </class>
- 实体类中添加主键对象字段:
public class FileEntity implements Serializable { private FileCompositeId id; // 其他业务属性 // 对应getter、setter方法 }
方式二:不使用独立主键类,但实体类必须规范实现
如果不想创建独立主键类,实体类必须满足:
- 正确实现
Serializable(注意你提供的代码中拼写错误为Serizalizable,必须修正) - 所有复合主键字段都在实体类中定义
- 基于所有主键字段正确重写
equals()和hashCode()方法
hbm.xml写法保持原有结构:
<class name="FileEntity" table="file_table" schema="schema1" catalog="demo"> <composite-id> <key-property name="id1" column="cl1"/> <key-property name="id2" column="cl2"/> </composite-id> <!-- 其他属性映射 --> </class>
实体类示例:
public class FileEntity implements Serializable { private int id1; private String id2; // 其他业务属性 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; FileEntity that = (FileEntity) o; return id1 == that.id1 && Objects.equals(id2, that.id2); } @Override public int hashCode() { return Objects.hash(id1, id2); } // 对应getter、setter方法 }
2. 修正SessionFactory配置的明显错误
你提供的SessionFactory配置中存在致命错误:<property name="datasource">引用的是demo.mappingRessource(映射资源),但该属性应该指向数据源Bean,映射资源需要单独配置在mappingResources属性下。修正后的配置如下:
<bean id="demo.sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <property name="hibernateProperties" ref="demo.hibernateProperties"/> <property name="entityInterceptor" ref="demo.myInterceptor"/> <!-- 修正:datasource指向数据源Bean --> <property name="dataSource" ref="demo.dataSource"/> <!-- 配置映射资源列表 --> <property name="mappingResources"> <list> <value>file1.hbm.xml</value> <value>other-entity.hbm.xml</value> <!-- 所有hbm.xml文件路径 --> </list> </property> </bean>
这个配置错误在Hibernate 3中可能未被严格校验,但Hibernate 5会直接导致初始化失败,必须优先修正。
3. 其他排查细节
- 检查所有hbm.xml的语法错误:比如你提供的示例中
<id ="fileId"缺少name属性,正确写法应为<id name="fileId" type="int">,这类语法错误在Hibernate 5中会触发解析异常 - 清理项目编译目录,重新编译,确保旧的class文件被完全替换
- 确保所有实体类(包括单主键实体)都正确实现
Serializable
内容的提问来源于stack exchange,提问作者clorzs
相关产品推荐
相关产品推荐

