替换Hibernate 5.2.12.Final废弃API遇属性定位异常求助
解决Hibernate 5.2中CriteriaBuilder无法识别hbm映射属性的问题
你遇到的这个问题确实和hbm.xml映射与JPA CriteriaBuilder的兼容性有关——JPA的CriteriaBuilder依赖于Hibernate构建的ManagedType元模型,而旧的hbm映射如果没有被正确解析为符合JPA规范的元模型,就会抛出"Unable to locate Attribute"异常。下面是一步步的排查和解决方案:
1. 核对hbm映射与实体类的属性一致性
首先要确保hbm.xml中的属性名和实体类的映射完全匹配:
- 打开你的
DonneeReference.hbm.xml,找到<class>标签确认对应的实体类是com...DonneeReference。 - 检查对应属性的配置:如果是普通属性,看
<property name="filtre" .../>的name值是否和实体类的字段名/ getter方法对应;如果是关联关系(比如<many-to-one>),同样确认name属性和实体类中的关联字段名一致。- 注意大小写!Hibernate的旧Criteria对大小写不敏感,但JPA CriteriaBuilder是严格匹配的,比如hbm里写的是
Filtre而你用root.get("filtre")就会报错。
- 注意大小写!Hibernate的旧Criteria对大小写不敏感,但JPA CriteriaBuilder是严格匹配的,比如hbm里写的是
2. 确认hbm文件被正确加载
如果Hibernate没有扫描到你的hbm.xml文件,就无法为对应的实体构建元模型,自然找不到属性:
- 如果你用
persistence.xml,确保添加了<mapping-file>标签指定hbm路径,比如:<persistence-unit name="yourPU"> <mapping-file>META-INF/DonneeReference.hbm.xml</mapping-file> <!-- 其他配置 --> </persistence-unit> - 如果你用Spring,检查
LocalSessionFactoryBean的mappingLocations属性是否包含了该hbm文件:@Bean public LocalSessionFactoryBean sessionFactory() { LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); sessionFactory.setMappingLocations(new ClassPathResource("DonneeReference.hbm.xml")); // 其他配置 return sessionFactory; }
3. 检查实体类的访问策略
hbm.xml中的access属性决定了Hibernate是通过字段还是getter/setter访问属性:
- 如果hbm里写了
<property name="filtre" access="field" .../>,那么实体类中必须有一个名为filtre的字段(不管getter/setter是否存在)。 - 如果是
access="property"(默认值),则实体类必须有对应的getFiltre()和setFiltre()方法,方法名要符合JavaBean规范(首字母大写,比如filtre对应getFiltre())。
4. 尝试使用Hibernate特定API兼容hbm映射
如果以上步骤都没问题,你可以尝试用Hibernate扩展的Criteria API来兼容hbm映射,虽然JPA的CriteriaBuilder是标准,但Hibernate提供了一些过渡方案:
HibernateCriteriaBuilder builder = (HibernateCriteriaBuilder) entityManager.getCriteriaBuilder(); CriteriaQuery<DonneeReference> criteria = builder.createQuery(DonneeReference.class); Root<DonneeReference> root = criteria.from(DonneeReference.class); criteria.where(builder.equal(root.get("filtre"), filtre));
5. 长期解决方案:迁移到注解映射
从Hibernate 5.x开始,官方对hbm.xml的支持逐渐弱化,注解映射是更符合JPA规范的长期方案。你可以逐步将hbm配置转换为实体类上的注解,比如:
@Entity @Table(name = "donnee_reference") public class DonneeReference { @Column(name = "filtre_col") private String filtre; // getter/setter }
迁移后,CriteriaBuilder的使用会更顺畅,也能避免类似的兼容性问题。
内容的提问来源于stack exchange,提问作者Anthony
相关产品推荐
相关产品推荐

