Hibernate的Criteria API - 添加左连接别名可减少结果数量

时间:2016-04-27 16:34:48

标签: java hibernate alias detachedcriteria

我遇到了Hibernate的Criteria API问题。由于未知原因,添加左连接类型别名会更改结果集。

我想在Criteria API中重新创建以下SQL查询:

    select distinct f.*
    from form_instance i
    join form_value v on v.form_instance_id = i.id
    join form_field f on f.form_field_id = v.form_field_id
    where
    (f.id = ? and v.value = ?)
    or (f.id = ? and v.value = ?)

映射(仅相关字段)来自遗留代码(我还没有在hibernate和复合ID中使用xml映射)。

FormInstance:

(我已经尝试过禁用延迟加载,没有效果)

    <set name="values" lazy="true" batch-size="200" cascade="all,delete-orphan" inverse="true"> 
      <key column="form_instance_id"/>
      <one-to-many class="FormValue" not-found="ignore" />
    </set>

FormValue:

    <composite-id>
      <key-many-to-one name="field"
            column="form_field_id"
            class="com.sales.model.FormField" />
      <key-many-to-one name="formInstance" column="form_instance_id" />
      <key-property column="value_index" name="valueIndex" />
    </composite-id>

FormField:

    <many-to-one class="com.sales.model.FormField" 
        column="parent_field_id" insert="false" 
        name="parentField" not-null="false" update="false"/>

我不会详细说明如何构建标准,因为它并不重要。为FormInstabnce.class创建了分离标准,然后添加了一些小限制。

当我执行hibernateTemplate.findByCriteria(detachedCriteria, 1, 10)时,我只得到1个结果,但是当我尝试计算不同的根实体时,结果是正确的(2000+结果)

    criteria.setProjection(Projections.countDistinct(rootEntityId));
    Long result = (Long) dataObjectDAO.findByCriteria(criteria, 1).get(0);

(在此操作之后我重置了投影和resultTransformer obvio

    criteria.setProjection(null);
    criteria.setResultTransformer(CRITERIA_RESULT_TRANSFORMER);

我已尝试调试此问题,当我向formValue添加别名时出现了问题(更改了结果计数):

detachedCriteria.createAlias("values", "values", CriteriaSpecification.LEFT_JOIN);

在调试过程中,我已经转储了执行的查询,并且在添加别名时存在差异 - 这可能暗示某人更熟练地使用Hibernate实际进行的操作。我用*替换了字段列表以提高可读性。

没有别名,结果正确:

select * from ( 
    select * 
    from bank.form_instance this_ 
    where this_.product=? 
    order by this_.pf_date desc 
) 
where rownum <= ?

使用别名,结果不正确(1行):

select * from ( 
    select *
    from bank.form_instance this_ 
    left outer join bank.form_value values1_ on this_.id=values1_.form_instance_id 
    where this_.product=? and ((this_.user_name=?)) order by this_.pf_date desc 
) 
where rownum <= ?

select *
from bank.form_field formfield0_ 
where formfield0_.form_field_id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

我已经尝试过深入调试,但是当我尝试在反编译的Hibernate类上进行调试时,我的IDE会失去同步,如果没有额外的工作,它就变得不可能了。

有趣的是,第二个查询只搜索10个formFields,尽管每个formInstance都有180个formFields,10个是传递给searchByCriteria方法的值。

我怀疑hibernate映射是不正确的,但我并不精通应该自己找出来。任何帮助都会深深感激,我现在​​坚持这个问题2天了,我真的很沮丧。

祝你好运, 尊利

0 个答案:

没有答案