我遇到了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天了,我真的很沮丧。
祝你好运, 尊利