关于Hibernate查询的ORA-01791

时间:2013-07-05 08:05:20

标签: sql hibernate

我的代码是:

Criteria criteriaA = getHibernateSession().createCriteria(entityA.class, "aaa");
Criteria criteriaB = criteriaA.createCriteria("entityB").setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); // It seems that the result transformer don't affect the code...

criteriaA.add( -- some restriction --)

if (orderById) {
    criteriaB.addOrder(Order.desc("id"));
}

if (!orderById && orderByDate) {
    criteriaB.addOrder(Order.desc("date"));
}

criteriaA.setProjection(Projections.distinct(Projections.property("entityB")));

entityA和entityB有一个oneMoMany关系支持(一个实体B可能有0 .. * entityA)但我只能从B导航到A(项目限制......不能改变)。
现在,问题是我在返回的结果中不需要重复,我需要对结果进行排序 奇怪的事实是ORA-01791(它告诉我有一个不正确的orderby)我只在按日期排序时启动,按id排序并没有给我任何问题,但两者都是我想要区分的实体的属性!登记/> 为什么我可以按ID而不是按日期排序? 还有另一种方法可以做我想做的事吗?
----编辑-----
正如maby建议我查看生成的查询:

DEBUG [org.hibernate.SQL]
select distinct this_.BBB_ID as y0_
from TB_ENTITY_A this_ 
inner join TB_ENTITY_B entityB_ on this_.BBB_ID=entityB_.BBB_ID 
where this_.ANOTHER_ID=? and lower(this_.AAA_VALUE) like ? and this_.AAA_ID in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
order by entityB_.BBB_DATE asc

所以,我的区别仅适用于外键的id ..
我如何强制Hibernate选择所有字段?
如果我这样做:

criteriaB.list();

而不是

criteriaA.list():

我会从条件A中丢失过滤器吗? 我也在考虑尝试从实体B中设置Projection所有字段,但我不确定hibernate是否可以将结果转换为实体。

4 个答案:

答案 0 :(得分:2)

http://ora-01791.ora-code.com/说:

  

在此上下文中,所有ORDER BY项必须是常量SELECT列表   表达式,或操作数为常量或SELECT的表达式   列表表达式

我猜你/ hibernate没有选择date。如果这样做,您可以将生成的SQL添加到问题中吗?

答案 1 :(得分:0)

对表或字段名称使用SQL关键字时会出现奇怪的问题。这可能就是这里发生的事情。只需尝试在您的实体属性上添加@Column(name = "date_")即可。

答案 2 :(得分:0)

mabi在他/她的猜测中是正确的。

您要做的是生成如下所示的查询:

select this_.BBB_ID as y0_, min(entityB_.BBB_DATE) as min_date
from TB_ENTITY_A this_ 
inner join TB_ENTITY_B entityB_ on this_.BBB_ID=entityB_.BBB_ID 
where this_.ANOTHER_ID=? and lower(this_.AAA_VALUE) like ? 
  and this_.AAA_ID in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
group by this_.BBB_ID
order by min_date asc

不知道如何在Hibernate中做到这一点。

但是,如果Hibernate无法使用返回的两列来管理ID,那么这样的查询应该可以正常工作:

select y0_ 
    from(
        select this_.BBB_ID as y0_, min(entityB_.BBB_DATE) as min_date
            from TB_ENTITY_A this_ 
                inner join TB_ENTITY_B entityB_ on this_.BBB_ID=entityB_.BBB_ID 
            where this_.ANOTHER_ID=? and lower(this_.AAA_VALUE) like ? 
              and this_.AAA_ID in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            group by this_.BBB_ID
    ) a
order by min_date asc

但是,再次,如何在Hibernate中做到这一点,我不知道。它认为可以添加自定义SQL / HQL,因此您应该能够以某种方式创建它。

答案 3 :(得分:0)

正如mabi建议我回答我的问题以发布我的解决方案:

----已解决-----

我改变了组织查询的方式:我为多方实体创建了一个独立的条件,并使用子查询检索另一个实体:

DetachedCriteria criteriaA = DetachedCriteria.forClass(EntityA.class, "aaa");
criteriaA.add( -- some restriction --);
criteriaA.setProjection(Projections.property("entityB"));

Criteria criteriaB = getHibernateSession().createCriteria(EntityB.class, "bbb");
criteriaB.add(Property.forName("id").in(criteriaA));

所以我不需要一个独特的,可以从实体B中为我想要的所有字段排序。