Hibernate4升级Hibernate5时列名与属性名不一致触发MappingException如何解决
Hibernate 4升级至5.4.32版本映射异常解决方案
根因说明
该问题是Hibernate 5.x的兼容性变更导致:Hibernate 5重构了DDL自动生成阶段的列名解析逻辑,当开启自动DDL生成配置时,会错误将@Column注解的name值作为实体属性名去查找对应字段,忽略了列名和实体属性名的映射关系,才会抛出找不到properties属性的异常,Hibernate 4无此逻辑所以运行正常。
你不需要修改第三方依赖的实体代码,可根据业务场景选择以下任意方案解决:
可选解决方案
- 方案1:关闭自动DDL生成(改动最小,优先推荐)
绝大多数线上环境不需要启动时自动修改表结构,直接修改两处配置即可:
修改后启动时不会再触发DDL生成逻辑,自然不会触发属性查找异常,完全不影响正常的CRUD业务逻辑。<!-- 1. 修改HibernateJpaVendorAdapter的generateDdl参数为false --> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="generateDdl" value="false" /> <property name="database" value="${cfl.database.dialect}" /> </bean> <!-- 2. 修改jpaPropertyMap中的hibernate.hbm2ddl.auto参数为none --> <entry key="hibernate.hbm2ddl.auto" value="none"/> - 方案2:注册Hibernate元数据扩展(需保留自动DDL时使用)
如果必须保留自动DDL能力,可通过Hibernate的MetadataContributor扩展点,手动添加属性别名映射:- 实现自定义元数据贡献类
import org.hibernate.boot.Metadata; import org.hibernate.boot.spi.BootstrapContext; import org.hibernate.boot.spi.MetadataContributor; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; public class CustomPropertyMappingContributor implements MetadataContributor { @Override public void contribute(Metadata metadata, BootstrapContext bootstrapContext) { PersistentClass entityMapping = metadata.getEntityBinding("xxx.model.MiscMessageProperties"); if (entityMapping != null) { // 拿到实际存在的value属性 Property valueProp = entityMapping.getProperty("value"); // 给properties查找设置别名,指向value属性 entityMapping.addProperty(valueProp, "properties"); } } }- 在jpaPropertyMap中注册该扩展
<entry key="hibernate.metadata_builder_contributor" value="你的自定义类全路径.CustomPropertyMappingContributor"/> - 方案3:XML映射覆盖注解配置
可在本地项目中添加Hibernate XML映射文件,优先级高于第三方实体的注解配置,无需修改第三方代码:
在src/main/resources下创建路径xxx/model/MiscMessageProperties.hbm.xml,内容如下:
最后在你的<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="xxx.model"> <class name="MiscMessageProperties" table="miscmessage_properties"> <id name="propertiesKey" class="xxx.model.PropertiesKey"> <!-- 配置主键对应字段,和原有注解逻辑一致即可 --> </id> <property name="value" column="properties" length="256"/> </class> </hibernate-mapping>persistence.xml中添加该映射文件的引用即可生效。
内容的提问来源于stack exchange,提问作者Uwe Allner
相关产品推荐
相关产品推荐

