質問

さまざまな言語固有の文字列を格納する Oracle XMLType 列があります。この列に基づいて順序付けする Hibernate 基準を構築する必要があります。これを行うには、Oracle 関数を使用して値を抽出する必要があります。この基準は、私が書いたコードによって自動的に生成されますが、基準 API を介して値を抽出し、それに基づいて順序付けする方法は、一生わかりません。基本的に、生成される SQL は次のようになります。

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

一時的に投影をいじりましたが、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')).

他のヒント

別の一般的な解決策はNativeSQLOrderで、のhttpを参照してください。//opensource.atlassian。 COM /プロジェクト/ /閲覧/ HHH-2381 に休止状態。この機能はまだ休止していない理由を私は、undestandしません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top