daybreaksnow's diary

私を私と呼びたい

[Hibernate]デフォルトで用意されているResultTransformerの利用

Criteriaに対し、ResultTransformerをセットすることで、取得される結果の形式を変換することができる。

デフォルトでは以下の四つがCriteriaSpecificationに用意されている。

変数名 クラス
ROOT_ENTITY(デフォルト) RootEntityResultTransformer
DISTINCT_ROOT_ENTITY DistinctRootEntityResultTransformer
ALIAS_TO_ENTITY_MAP AliasToEntityMapResultTransformer
PROJECTION PassThroughResultTransformer

・サンプルテーブル構成
ItemとBidが1:nの関係になっている。

・Item

item_id
1

・Bid

bid_id item_id
1 1
2 1
3 1


以下のクライテリアに対しResultTransformerをセットした際の結果の違い

Criteria criteria = session.createCriteria(Item.class);
criteria.addAlias("bids","bidAlias");
criteria.setResultTransformer(XXX); //設定するResultTransformerを変更する
criteria.list();

ROOT_ENTITY

listの結果サイズ:3
listの結果の型:Item

同じインスタンスが3つ入っている。

DISTINCT_ROOT_ENTITY

listの結果サイズ:1
listの結果の型:Item

ROOT_ENTITYと同じインスタンスが一つだけ(distinctされて)取得できる。

ALIAS_TO_ENTITY_MAP

listの結果サイズ:3
listの結果の型:Map

keyがエイリアス名、valueがエンティティとなる。
今回の例だと、{this,item}と{bidAlias,bid}が取得できる。

PROJECTION

listの結果サイズ:3
listの結果の型:Object[2]

[0]にBidが、[1]にItemが入っている


上記の通り、デフォルトのROOT_ENTITYのままだと、エイリアスを付けた際に同じオブジェクトが複数結果に含まれてしまう。
エイリアスを使う際はDISTINCT_ROOT_ENTITYをセットしておけばよいだろう。

なお、PROJECTIONについては、criteria.setProjectionの呼び出し時に自動で設定されている。