Hibernate Computed Criteria Order

时间:2010-02-09 00:59:33

标签: oracle hibernate sorting criteria xmltype

我有一个Oracle XMLType列,用于存储各种特定于语言的字符串。我需要构建一个在此列上排序的Hibernate标准。为此,我需要使用Oracle函数提取值。这个标准是由我编写的代码自动生成的,但在我的生活中,我不能通过标准API找出如何提取它的价值和顺序。基本上,生成的SQL应该类似于:

SELECT EXTRACTVALUE(title, '//value[@lang="EN"]') AS enTitle
FROM domain_object 
ORDER BY enTitle

我暂时摆弄了投影,但他们似乎执行了第二次选择。我假设会导致hibernate选择所有值,并在内存中根据投影对它们进行排序?这将是非常不受欢迎的= \

2 个答案:

答案 0 :(得分:2)

好的,我找到了一个解决方案。不确定这是最好的,所以如果有人希望提供更好的答案/改进我的解决方案,我会暂时保持开放状态。

我所做的是如此延伸org.hibernate.criterion.Order

package com.mycorp.common.hibernate;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Order;
import org.hibernate.engine.SessionFactoryImplementor;

import com.mycorp.LocalizationUtil;

public class LocalStringOrder extends Order {
    private static final long serialVersionUID = 1L;

    private boolean ascending;
    private String  propName;

    public LocalStringOrder(String prop, boolean asc) {
        super(prop, asc);
        ascending    = asc;
        propName = prop;
    }

    public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
        String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propName);
        StringBuffer fragment = new StringBuffer();
        for ( int i=0; i<columns.length; i++ ) {
            SessionFactoryImplementor factory = criteriaQuery.getFactory();
            fragment.append( factory.getDialect().getLowercaseFunction() )
            .append('(');
            fragment.append("EXTRACTVALUE(");
            fragment.append( columns[i] );
            fragment.append(", '//value[@lang=\"" + 
                LocalizationUtil.getPreferedLanguage().name() + 
                "\"')");
            fragment.append(')');
            fragment.append( ascending ? " asc" : " desc" );
            if ( i<columns.length-1 ) fragment.append(", ");
        }
        return fragment.toString();
    }

    public static Order asc(String propertyName) {
        return new LocalStringOrder(propertyName, true);
    }


    public static Order desc(String propertyName) {
        return new LocalStringOrder(propertyName, false);
    }
}

然后只是说criteria.addOrder(LocalStringOrder.asc('prop'))

答案 1 :(得分:1)

另一个通用解决方案是Native SQL Order,请参阅http://opensource.atlassian.com/projects/hibernate/browse/HHH-2381。我不明白,为什么这个功能还没有在Hibernate中。