1

これは私が持っているSQLステートメントです。

SELECT USER_PROFILE.FIRST_NAME, USER_PROFILE.LAST_NAME, USER_PROFILE.USER_TYPE
FROM USER_PROFILE
INNER JOIN USER_LOGIN_STATUS
ON USER_PROFILE.USER_ID=USER_LOGIN_STATUS.USER_ID
ORDER BY USER_PROFILE.FIRST_NAME

そして、私は休止状態の DetachedCriteria に相当すると考え、結果として 2 つのデータしか持たないと予想される以下のコードを実行しようとしています。

DetachedCriteria dc = getDetachedCriteria();
DetachedCriteria userLoginCriteria = DetachedCriteria.forClass(UserLoginStatus.class);
userLoginCriteria.setProjection(Projections.distinct(Projections.property("userId")));
dc.add(Subqueries.propertyIn(UserField.id.name(), userLoginCriteria));

DetachedCriteria profileCriteria = dc.createCriteria("profile");
profileCriteria.addOrder(Order.asc("firstName"));
return getAll(dc, pageSetting);

しかし残念ながら、これは予期しない結果です。複数のデータの結果が得られました。

名前 | タイプ |

  1. ベン・ジョーンズ | ユーザー |
  2. ベン・ジョーンズ | ユーザー |
  3. トム・ホーマー | ゲスト |
  4. トム・ホーマー | ゲスト |

正確に同等の DetachedCriteria またはこれに対する解決策を知っている人はいますか?

4

2 に答える 2

1

まず第一に、SQL が間違っているように見えます。複数の行を返す理由は、USER_LOGIN_STATUSごとに複数の行を持つ可能性のあるテーブルに対して結合しているためですUSER_PROFILE。テーブルからフィールドを選択していないためUSER_LOGIN_STATUS、行が複数ある理由がわかりません。そもそもなぜこのテーブルに参加しているのですか?

次に、SQL に含まれていないサブクエリを実行しているため、実行している切り離された基準は、提供した SQL と同等ではありません。

この副選択は必要ありません。結合を行っている理由がわからないので、次の例を示すためにいくつかの点を想定します。

DetachedCriteria dc = getDetachedCriteria();
dc.createAlias("userLoginStatus", "uls");
dc.add(Projections.property("firstName")); 
dc.add(Projections.property("lastName"));
dc.add(Projections.property("userType")); 
dc.addOrder(Order.asc("firstName")); 
return getAll(dc, pageSetting);

これは現在ほぼ同等ですが、私は次のように仮定しています:

  • と の間の関係の正しいマッピングがUserFieldありますUserLoginStatus
  • それgetDetachedCriteria()は効果的に返されDetachedCriteria.forClass(UserField.class)ます。

次のようにフィールドを参照することもできますUserLoginStatus

dc.add(Projections.property("uls.my_user_login_field"));

また、クエリを整理しても複数のエンティティが返される場合、dinukadev の回答は次のようになります。

dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

これが機能しない理由は、サブセレクトが原因だと思います。

申し訳ありませんが、これ以上お手伝いすることはできません。

于 2013-01-08T09:32:47.440 に答える
0

次のように、ルートデタッチ基準に結果トランスフォーマーを設定してみてください。これにより、重複が排除されます。

dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);  
于 2013-01-04T03:55:17.283 に答える