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

Hibernate配置many-to-one not-found=ignore后Criteria查询报错的解决咨询

问题

数据表中存在指向不存在记录的关联,为了提取带有断链的对象,在Hibernate映射文件中为many-to-one配置了not-found="ignore",配置代码如下:

<class name="pattern" table="PATTERN">
    <id name="un" type="long">
        <column name="UN" precision="10" scale="0" />
        <generator class="native"/>
    </id>
    <many-to-one class="Workplace" fetch="select" lazy="false" name="workplace" not-found="ignore">
        <column name="UN" not-null="true"/>
    </many-to-one>
...
</class>

<class name="Workplace" table="WORKPLACE">
    <id name="un" type="long">
        <column name="UN" precision="10" scale="0" />
        <generator class="assigned"/>
    </id>
...
</class>

此时可成功获取对象,但使用Criteria添加Restrictions.eq("workplace.un", un)查询时,出现错误:

could not resolve property: workplace.un of: pattern
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:285)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:230)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708)
    at 

若移除not-found="ignore",查询正常但无法获取带断链的对象,请问能否修复该查询问题?

解决方案

可以修复,核心原因是not-found="ignore"会让Hibernate在关联对象不存在时将workplace设为null,但使用Criteria查询workplace.un时,Hibernate会尝试解析关联属性的路径,当workplace为null时就会报错。这里提供几种可行的解决办法:

  • 直接关联数据库字段查询
    既然pattern表中存储关联的是WORKPLACE的UN字段,直接用该字段做查询条件即可,不需要通过关联对象的属性。把Restrictions.eq("workplace.un", un)改成Restrictions.eq("UN", un)(直接用数据库列名,若有表名冲突可加上表别名,比如p.UN)。

  • 使用SQLQuery替代Criteria
    直接写原生SQL查询,绕开Hibernate的关联属性解析问题。示例:

    SELECT p.* FROM PATTERN p WHERE p.UN = :un
    

    通过createSQLQuery执行后,将结果转换为Pattern对象即可。

  • 添加独立字段映射
    在Pattern类中新增一个对应关联列的属性(比如workplaceUn),并在映射文件中配置单独的<property>标签:

    <property name="workplaceUn" column="UN" type="long"/>
    

    之后用Restrictions.eq("workplaceUn", un)查询,同时保留many-to-one的not-found="ignore"配置,既能获取带断链的对象,又能正常执行查询。

  • 用DetachedCriteria处理关联与null场景
    如果坚持用Criteria关联查询,可以通过DetachedCriteria同时处理关联存在和workplace为null的情况:

    Criteria criteria = session.createCriteria(Pattern.class);
    // 关联存在的情况
    DetachedCriteria workplaceSubQuery = DetachedCriteria.forClass(Workplace.class)
        .add(Restrictions.eq("un", un))
        .setProjection(Projections.id());
    // 组合条件:关联存在 或者 关联为null(断链对象)
    criteria.add(Restrictions.or(
        Restrictions.isNull("workplace"),
        Subqueries.propertyIn("workplace.un", workplaceSubQuery)
    ));
    

    这种方式相对复杂,适合必须用Criteria的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 09:54:52