You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate5.6+Spring5.3中无法定位userName属性的问题求助

Hibernate 5.6 + Spring 5.3中Criteria API无法识别复合ID属性的问题

问题场景

在Hibernate 5.6搭配Spring 5.3环境下,使用Criteria API查询UmsUserRoleVOImpl实体时,尝试通过root.get("userName")获取属性触发异常,尽管实体类中存在该属性且已通过hbm.xml完成映射。

错误信息

java.lang.IllegalArgumentException: Unable to locate Attribute with the given name [userName] on this ManagedType [com.myapp.ums.business.impl.UmsUserRoleVOImpl]

相关代码

1. Criteria查询代码

CriteriaBuilder cb = this.getSession().getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery(aliasToBeanClass);
Root root = cq.from(aliasToBeanClass); // aliasToBeanClass设置为UmsUserRoleVOImpl
    
predicates.add(cb.equal(root.get(key), value)); // key设置为"userName" - 此行触发异常

2. Hibernate映射文件(hbm.xml)

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.myapp.ums.business.impl.UmsUserRoleVOImpl" table="ums_t_user_role"
           proxy="com.myapp.ums.common.business.UmsUserRoleVO">
        <composite-id>
            <key-property name="userName" type="java.lang.String" column="fk_user_id"/>
            <key-property name="roleName" type="java.lang.String" column="fk_role_id"/>
        </composite-id>
    </class>
</hibernate-mapping>

3. UmsUserRoleVOImpl核心代码

public class UmsUserRoleVOImpl extends AbstractBasePropertiesImpl implements UmsUserRoleVO {
 
    private static final long serialVersionUID = 2393634151578825216L;

    private String roleName;
    private String userName;
    private List<PmPropertyVO> properties;

    // 父类方法与其他省略代码...

    @Get(UmsUserRoleVO.USER_NAME)
    public String getUserName() {
        return this.userName;
    }

    @Set(UmsUserRoleVO.USER_NAME)
    public void setUserName(String userName) {
        this.userName = userName;
    }

    @Get(UmsUserRoleVO.ROLE_NAME)
    public String getRoleName() {
        return roleName;
    }

    @Set(UmsUserRoleVO.ROLE_NAME)
    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }
}

原因分析

  1. 复合ID的元数据封装规则:Hibernate会将<composite-id>中的属性整体封装为一个单独的ID属性(默认名称为id),而非将其作为实体的普通属性。直接使用root.get("userName")访问会绕过ID属性的层级,导致无法找到对应属性。
  2. 映射文件未正确加载:如果hbm.xml文件未被Spring或Hibernate的配置扫描到,实体的元数据不会包含这些属性,也会触发该异常。
  3. 自定义注解的兼容性:实体类使用了自定义的@Get/@Set注解而非JPA标准注解,若Hibernate元数据处理器无法识别这些注解,可能导致属性解析异常。

解决方案

方案1:通过复合ID层级访问属性

针对复合ID中的属性,需要通过ID属性的路径进行访问,默认情况下使用id作为复合ID的名称:

predicates.add(cb.equal(root.get("id").get("userName"), value));

如果在hbm.xml中给<composite-id>设置了name属性(比如name="userRoleId"),则使用对应的名称访问:

predicates.add(cb.equal(root.get("userRoleId").get("userName"), value));

方案2:确保映射文件被正确加载

检查Spring配置,确保hbm.xml所在路径被纳入扫描范围。示例配置:

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="mappingLocations" value="classpath:com/myapp/ums/business/impl/*.hbm.xml"/>
    <!-- 其他数据源、hibernate属性配置 -->
</bean>

方案3:验证自定义注解兼容性

临时替换自定义注解为JPA标准注解(如@Column)进行测试,确认是否是注解解析问题;若必须使用自定义注解,需确保Hibernate的元数据处理器能正确识别这些注解的逻辑。

内容的提问来源于stack exchange,提问作者d00d

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 02:41:05