[Hibernate]sqlRestriction使用時のエイリアス名の解決方法
sqlRestrictionでは、ルートとなるエンティティのエイリアスは{alias}で取得できるが、
joinしたエンティティのエイリアスは取得できない。
例
Criteria criteria = session.createCriteria(Bid.class); criteria.createAlias("item", "aliasItem"); criteria.add(Restrictions.sqlRestriction("{alias}.amount = 1")); criteria.add(Restrictions.sqlRestriction("aliasItem.name = 'hoge'"));
発行されるSQL
select this_.bid_id as bid1_3_1_, this_.item_id as item2_3_1_, this_.amount as amount3_1_, aliasitem1_.item_id as item1_4_0_, aliasitem1_.name as name4_0_ from public.bid this_ inner join public.item aliasitem1_ on this_.item_id=aliasitem1_.item_id where this_.amount = 1 and aliasItem.name = 'hoge'
上記のとおり、ソースコード上で"aliasItem"と指定したエイリアス名が、実際に発行されるSQLではaliasitem1_となってしまう。
そのため、このコードは実行時に例外が発生する。
この問題を解決するには、createAliasではなく、createCriteriaを使えばよい。
参考URL:
http://ch-express.blogspot.jp/2008/06/hibernate-criteria-sqlrestriction-alias.html
上記のSQLを書き換えた例
Criteria criteria = session.createCriteria(Bid.class); criteria.add(Restrictions.sqlRestriction("{alias}.amount = 1")); Criteria subCriteria = criteria.createCriteria("item"); subCriteria.add(Restrictions.sqlRestriction("{alias}.name = 'hoge'"));
発行されるSQL
select this_.bid_id as bid1_3_1_, this_.item_id as item2_3_1_, this_.amount as amount3_1_, item1_.item_id as item1_4_0_, item1_.name as name4_0_, from public.bid this_ inner join public.item item1_ on this_.item_id=item1_.item_id where this_.amount = 1 and item1_.name = 'hoge'
createAliasとcreateCriteriaを混ぜることも可能。
Criteria criteria = session.createCriteria(Bid.class); criteria.createAlias("item", "aliasItem"); Criteria subCriteria = criteria.createCriteria("item.mapping"); subCriteria.add(Restrictions.sqlRestriction("{alias}.id = 1"));