23

簡単に言うと、休止状態は例によるプロジェクションとクエリをサポートしていませんか?私はこの投稿を見つけました:

コードは次のとおりです。

User usr = new User();
usr.setCity = 'TEST';
getCurrentSession().createCriteria(User.class)
.setProjection( Projections.distinct( Projections.projectionList()
.add( Projections.property("name"), "name")
.add( Projections.property("city"), "city")))
.add( Example.create(usr))

他のポスターが言ったように、生成されたSQLは、y0_ =だけを参照するwhereクラスを持ち続けますか?this_.cityの代わりに

私はすでにいくつかのアプローチを試し、課題追跡システムを検索しましたが、これについては何も見つかりませんでした。

ProjectionエイリアスとTransformersを使用しようとしましたが、機能しません。

User usr = new User();
usr.setCity = 'TEST';
getCurrentSession().createCriteria(User.class)
.setProjection( Projections.distinct( Projections.projectionList()
.add( Projections.property("name"), "name")
.add( Projections.property("city"), "city")))
.add( Example.create(usr)).setResultTransformer(Transformers.aliasToBean(User.class));

誰かが例による射影とクエリを使用しましたか?

4

6 に答える 6

45

この問題は、objectsプロパティと同じ名前のエイリアスがある場合に発生するようです。Hibernateはエイリアスを取得し、SQLで使用しているようです。これはここここで文書化されていることがわかりました。Hibernateチームが同意するかどうかはわかりませんが、Hibernateのバグであると思います。

いずれにせよ、私の場合はうまくいく簡単な回避策を見つけました。あなたのマイレージは異なる場合があります。詳細は以下のとおりです。このサンプルのコードを簡略化しようとしたので、エラーやタイプミスについてお詫びします。

Criteria criteria = session.createCriteria(MyClass.class)
    .setProjection(Projections.projectionList()
        .add(Projections.property("sectionHeader"), "sectionHeader")
        .add(Projections.property("subSectionHeader"), "subSectionHeader")
        .add(Projections.property("sectionNumber"), "sectionNumber"))
    .add(Restrictions.ilike("sectionHeader", sectionHeaderVar)) // <- Problem!
    .setResultTransformer(Transformers.aliasToBean(MyDTO.class));

このSQLを生成します:

select
    this_.SECTION_HEADER as y1_,
    this_.SUB_SECTION_HEADER as y2_,
    this_.SECTION_NUMBER as y3_,
from
    MY_TABLE this_ 
where
    ( lower(y1_) like ? ) 

エラーの原因:java.sql.SQLException:ORA-00904: "Y1_":無効な識別子

しかし、「これ」を使用するように制限を変更すると、次のようになります。

Criteria criteria = session.createCriteria(MyClass.class)
    .setProjection(Projections.projectionList()
        .add(Projections.property("sectionHeader"), "sectionHeader")
        .add(Projections.property("subSectionHeader"), "subSectionHeader")
        .add(Projections.property("sectionNumber"), "sectionNumber"))
    .add(Restrictions.ilike("this.sectionHeader", sectionHeaderVar)) // <- Problem Solved!
    .setResultTransformer(Transformers.aliasToBean(MyDTO.class));

次のSQLが生成され、問題は解決しました。

select
    this_.SECTION_HEADER as y1_,
    this_.SUB_SECTION_HEADER as y2_,
    this_.SECTION_NUMBER as y3_,
from
    MY_TABLE this_ 
where
    ( lower(this_.SECTION_HEADER) like ? ) 

それでおしまい!痛みを伴う問題に対する非常に簡単な修正。この修正が例によるクエリにどのように変換されるかはわかりませんが、問題が発生する可能性があります。

于 2009-06-06T18:41:58.247 に答える
16

User クラスを確認できますか? これは、以下の制限を使用しているだけです。制限が実際に例とまったく異なる理由がわかりません(ただし、例ではデフォルトでnullフィールドが無視されると思います)。

getCurrentSession().createCriteria(User.class)
.setProjection( Projections.distinct( Projections.projectionList()
.add( Projections.property("name"), "name")
.add( Projections.property("city"), "city")))
.add( Restrictions.eq("city", "TEST")))
.setResultTransformer(Transformers.aliasToBean(User.class))
.list();

私はalaistToBeanを使ったことはありませんが、それについて読んだだけです。結果をループすることもできます..

List<Object> rows = criteria.list();
for(Object r: rows){
  Object[] row = (Object[]) r;
  Type t = ((<Type>) row[0]);
}

必要な場合は、そのようにユーザー自身を手動で設定できます。

問題を診断するための追加情報がなければ、問題を調査するのは難しいです。

于 2008-09-17T19:34:29.767 に答える
6

ここでの本当の問題は、hibernate にバグがあり、where 句で select-list エイリアスを使用していることです。

http://opensource.atlassian.com/projects/hibernate/browse/HHH-817

誰かが答えを探してここにたどり着いた場合に備えて、チケットを見てください。修正に 5 年かかりましたが、理論的には次のリリースの 1 つに含まれる予定です。その後、問題は解消されると思います。

于 2010-09-15T17:42:46.880 に答える
0
ProjectionList pl = Projections.projectionList();
pl.add(Projections.property("id"));
pl.add(Projections.sqlProjection("abs(`pageNo`-" + pageNo + ") as diff", new String[] {"diff"}, types ), diff); ---- solution
crit.addOrder(Order.asc("diff"));
crit.setProjection(pl);
于 2016-02-13T15:11:08.050 に答える
0

私は同様の問題に直面しています。Query by Example を使用しており、結果をカスタム フィールドで並べ替えたいと考えています。SQLでは、次のようなことをします:

select pageNo, abs(pageNo - 434) as diff
from relA
where year = 2009
order by diff

order-by-clause がなくても問題なく動作します。私が得たものは

Criteria crit = getSession().createCriteria(Entity.class);
crit.add(exampleObject);
ProjectionList pl = Projections.projectionList();
pl.add( Projections.property("id") );
pl.add(Projections.sqlProjection("abs(`pageNo`-"+pageNo+") as diff", new String[] {"diff"}, types ));
crit.setProjection(pl);

しかし、追加すると

crit.addOrder(Order.asc("diff"));

org.hibernate.QueryException: could not resolve property: diff例外が発生します。これによる回避策も機能しません。

PS: Hibernate での QBE の使用に関する精巧なドキュメントを見つけることができなかったため、上記のすべてのものは主に試行錯誤のアプローチです

于 2009-06-10T16:07:38.527 に答える
-1

あまりそうは思いませんが、見つけられるのは「これ」という言葉です。休止状態がそのクエリに制限を含めないようにします。これは、すべてのレコード リストを取得したことを意味します。報告された休止状態のバグについては、修正済みと報告されていますが、パッチのダウンロードに完全に失敗しました。

于 2011-07-11T08:11:08.127 に答える