1

我的代码是:

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 有一个 oneToMany 关系(一个 entityB 可能有 0..* entityA),但我只能从 B 导航到 A(项目限制..不能改变它)。
现在,问题是我不需要在返回的结果中重复,我需要对我的结果进行排序。
奇怪的事实是 ORA-01791(告诉我有一个不正确的 orderby)我仅在按日期排序时启动,按 id 排序并没有给我任何问题,但两者都是我想要区分的实体的属性!
为什么我可以按 id 排序但不能按日期排序?
还有另一种方法可以做我想做的事情吗?

---- 编辑 -----
正如可能建议的那样,我查看了生成的查询:

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

所以,我的 distinct where 仅应用于外键的 id 。
我怎么能强制 Hibernate 选择所有字段?
如果我做:

criteriaB.list();

代替

criteriaA.list():

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

4

4 回答 4

2

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

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

我冒险猜测你/休眠不要选择date。如果这样做,您可以将生成的 SQL 添加到问题中吗?

于 2013-07-05T08:11:46.770 回答
0

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

于 2013-07-05T08:26:08.887 回答
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,因此您应该能够以某种方式创建它。

于 2013-07-05T09:00:30.310 回答
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 中对我想要的所有字段进行排序。

于 2013-07-05T16:42:08.113 回答