This is definitely a Hibernate bug.
@see
http://omgili.com/jmp/.wHSUbtEfZS3_Sqsw ... oKpU1RSW0-When I setup my criteria like this:
Code:
Criteria crit = sessionFactory.getCurrentSession().createCriteria(Title.class);
crit.createAlias("titleLanguageDataInternal", "tld", JoinFragment.INNER_JOIN);
crit.add(Restrictions.ilike("tld.titleString", "%Test%"));
crit.setFetchMode("titleLanguageDataInternal", FetchMode.JOIN);
crit.setFetchMode("titleLanguageDataInternal.language", FetchMode.JOIN);
crit.setFetchMode("categoriesInternal", FetchMode.JOIN);
crit.setFetchMode("categoriesInternal.parentCategory", FetchMode.JOIN);
crit.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
crit.setCacheMode(CacheMode.IGNORE);
return crit.list();
Hibernate runs the N+1 select to populate the collections:
Code:
Hibernate: select this_.title_pk as title1_1184_4_, this_.asset_billing_state_fk as asset2_1184_4_, this_.adult as adult1184_4_, this_.length as length1184_4_, this_.box_office as box5_1184_4_, this_.status as status1184_4_, this_.director as director1184_4_, this_.producer as producer1184_4_, this_.actors as actors1184_4_, this_.macrovision as macrovi10_1184_4_, this_.rank as rank1184_4_, this_.year as year1184_4_, tld1_.title_lang_data_pk as title1_1185_0_, tld1_.title_fk as title2_1185_0_, tld1_.language_fk as language3_1185_0_, tld1_.title as title1185_0_, tld1_.synopsis as synopsis1185_0_, language4_.language_pk as language1_1183_1_, language4_.language as language1183_1_, language4_.abbr as abbr1183_1_, categories5_.title_fk as title2_6_, category6_.category_pk as category1_6_, category6_.category_pk as category1_1179_2_, category6_.property_fk as property2_1179_2_, category6_.parent_category as parent3_1179_2_, category6_.name as name1179_2_, category6_.list_order as list5_1179_2_, category6_.active as active1179_2_, category6_.adult as adult1179_2_, category7_.category_pk as category1_1179_3_, category7_.property_fk as property2_1179_3_, category7_.parent_category as parent3_1179_3_, category7_.name as name1179_3_, category7_.list_order as list5_1179_3_, category7_.active as active1179_3_, category7_.adult as adult1179_3_ from title this_ inner join title_lang_data tld1_ on this_.title_pk=tld1_.title_fk left outer join languages language4_ on tld1_.language_fk=language4_.language_pk left outer join title_x_category categories5_ on this_.title_pk=categories5_.title_fk left outer join category category6_ on categories5_.category_fk=category6_.category_pk left outer join category category7_ on category6_.parent_category=category7_.category_pk where tld1_.title ilike ?
Hibernate: select studio0_.studio_pk as studio1_1187_, studio0_.country as country1187_, studio0_.state as state1187_, studio0_.name as name1187_, studio0_.main_phone_number as main5_1187_, studio0_.street as street1187_, studio0_.city as city1187_, studio0_.zip as zip1187_, studio0_.active as active1187_, studio0_.studio_abbr as studio10_1187_ from studio studio0_ where studio0_.active=1 order by studio0_.name
Hibernate: select encoder0_.encoder_pk as encoder1_1189_, encoder0_.country as country1189_, encoder0_.state as state1189_, encoder0_.name as name1189_, encoder0_.main_phone_number as main5_1189_, encoder0_.street as street1189_, encoder0_.city as city1189_, encoder0_.zip as zip1189_, encoder0_.active as active1189_ from encoder encoder0_ where encoder0_.active=1 order by encoder0_.name
Hibernate: select encoding0_.encoding_pk as encoding1_1192_0_, definition1_.definition_pk as definition1_1191_1_, encoding0_.definition_fk as definition2_1192_0_, encoding0_.encoding as encoding1192_0_, definition1_.name as name1191_1_, definition1_.abbr as abbr1191_1_ from encoding encoding0_ inner join definition definition1_ on encoding0_.definition_fk=definition1_.definition_pk order by encoding0_.encoding
Hibernate: select language0_.language_pk as language1_1183_, language0_.language as language1183_, language0_.abbr as abbr1183_ from languages language0_ where language0_.language_pk>=? order by language0_.language_pk
Hibernate: select language0_.language_pk as language1_1183_, language0_.language as language1183_, language0_.abbr as abbr1183_ from languages language0_ where language0_.language_pk>=? order by language0_.language_pk
Hibernate: select titlelangu0_.title_fk as title2_1_, titlelangu0_.title_lang_data_pk as title1_1_, titlelangu0_.title_lang_data_pk as title1_1185_0_, titlelangu0_.title_fk as title2_1185_0_, titlelangu0_.language_fk as language3_1185_0_, titlelangu0_.title as title1185_0_, titlelangu0_.synopsis as synopsis1185_0_ from title_lang_data titlelangu0_ where titlelangu0_.title_fk=?
Hibernate: select titlelangu0_.title_fk as title2_1_, titlelangu0_.title_lang_data_pk as title1_1_, titlelangu0_.title_lang_data_pk as title1_1185_0_, titlelangu0_.title_fk as title2_1185_0_, titlelangu0_.language_fk as language3_1185_0_, titlelangu0_.title as title1185_0_, titlelangu0_.synopsis as synopsis1185_0_ from title_lang_data titlelangu0_ where titlelangu0_.title_fk=?
Hibernate: select titlelangu0_.title_fk as title2_1_, titlelangu0_.title_lang_data_pk as title1_1_, titlelangu0_.title_lang_data_pk as title1_1185_0_, titlelangu0_.title_fk as title2_1185_0_, titlelangu0_.language_fk as language3_1185_0_, titlelangu0_.title as title1185_0_, titlelangu0_.synopsis as synopsis1185_0_ from title_lang_data titlelangu0_ where titlelangu0_.title_fk=?
Hibernate: select titlelangu0_.title_fk as title2_1_, titlelangu0_.title_lang_data_pk as title1_1_, titlelangu0_.title_lang_data_pk as title1_1185_0_, titlelangu0_.title_fk as title2_1185_0_, titlelangu0_.language_fk as language3_1185_0_, titlelangu0_.title as title1185_0_, titlelangu0_.synopsis as synopsis1185_0_ from title_lang_data titlelangu0_ where titlelangu0_.title_fk=?
Hibernate: select titlelangu0_.title_fk as title2_1_, titlelangu0_.title_lang_data_pk as title1_1_, titlelangu0_.title_lang_data_pk as title1_1185_0_, titlelangu0_.title_fk as title2_1185_0_, titlelangu0_.language_fk as language3_1185_0_, titlelangu0_.title as title1185_0_, titlelangu0_.synopsis as synopsis1185_0_ from title_lang_data titlelangu0_ where titlelangu0_.title_fk=?
Hibernate: select titlelangu0_.title_fk as title2_1_, titlelangu0_.title_lang_data_pk as title1_1_, titlelangu0_.title_lang_data_pk as title1_1185_0_, titlelangu0_.title_fk as title2_1185_0_, titlelangu0_.language_fk as language3_1185_0_, titlelangu0_.title as title1185_0_, titlelangu0_.synopsis as synopsis1185_0_ from title_lang_data titlelangu0_ where titlelangu0_.title_fk=?
Hibernate: select titlelangu0_.title_fk as title2_1_, titlelangu0_.title_lang_data_pk as title1_1_, titlelangu0_.title_lang_data_pk as title1_1185_0_, titlelangu0_.title_fk as title2_1185_0_, titlelangu0_.language_fk as language3_1185_0_, titlelangu0_.title as title1185_0_, titlelangu0_.synopsis as synopsis1185_0_ from title_lang_data titlelangu0_ where titlelangu0_.title_fk=?
Hibernate: select titlelangu0_.title_fk as title2_1_, titlelangu0_.title_lang_data_pk as title1_1_, titlelangu0_.title_lang_data_pk as title1_1185_0_, titlelangu0_.title_fk as title2_1185_0_, titlelangu0_.language_fk as language3_1185_0_, titlelangu0_.title as title1185_0_, titlelangu0_.synopsis as synopsis1185_0_ from title_lang_data titlelangu0_ where titlelangu0_.title_fk=?
Hibernate: select titlelangu0_.title_fk as title2_1_, titlelangu0_.title_lang_data_pk as title1_1_, titlelangu0_.title_lang_data_pk as title1_1185_0_, titlelangu0_.title_fk as title2_1185_0_, titlelangu0_.language_fk as language3_1185_0_, titlelangu0_.title as title1185_0_, titlelangu0_.synopsis as synopsis1185_0_ from title_lang_data titlelangu0_ where titlelangu0_.title_fk=?
Hibernate: select titlelangu0_.title_fk as title2_1_, titlelangu0_.title_lang_data_pk as title1_1_, titlelangu0_.title_lang_data_pk as title1_1185_0_, titlelangu0_.title_fk as title2_1185_0_, titlelangu0_.language_fk as language3_1185_0_, titlelangu0_.title as title1185_0_, titlelangu0_.synopsis as synopsis1185_0_ from title_lang_data titlelangu0_ where titlelangu0_.title_fk=?
Hibernate: select titlelangu0_.title_fk as title2_1_, titlelangu0_.title_lang_data_pk as title1_1_, titlelangu0_.title_lang_data_pk as title1_1185_0_, titlelangu0_.title_fk as title2_1185_0_, titlelangu0_.language_fk as language3_1185_0_, titlelangu0_.title as title1185_0_, titlelangu0_.synopsis as synopsis1185_0_ from title_lang_data titlelangu0_ where titlelangu0_.title_fk=?
Hibernate: select titlelangu0_.title_fk as title2_1_, titlelangu0_.title_lang_data_pk as title1_1_, titlelangu0_.title_lang_data_pk as title1_1185_0_, titlelangu0_.title_fk as title2_1185_0_, titlelangu0_.language_fk as language3_1185_0_, titlelangu0_.title as title1185_0_, titlelangu0_.synopsis as synopsis1185_0_ from title_lang_data titlelangu0_ where titlelangu0_.title_fk=?
Hibernate: select titlelangu0_.title_fk as title2_1_, titlelangu0_.title_lang_data_pk as title1_1_, titlelangu0_.title_lang_data_pk as title1_1185_0_, titlelangu0_.title_fk as title2_1185_0_, titlelangu0_.language_fk as language3_1185_0_, titlelangu0_.title as title1185_0_, titlelangu0_.synopsis as synopsis1185_0_ from title_lang_data titlelangu0_ where titlelangu0_.title_fk=?
However, when I change only the JOIN type from INNER_JOIN to LEFT_OUTER_JOIN, only the one query is run to fetch the collections:Code:
Criteria crit = sessionFactory.getCurrentSession().createCriteria(Title.class);
crit.createAlias("titleLanguageDataInternal", "tld", JoinFragment.LEFT_OUTER_JOIN);
crit.add(Restrictions.ilike("tld.titleString", "%Test%"));
crit.setFetchMode("titleLanguageDataInternal", FetchMode.JOIN);
crit.setFetchMode("titleLanguageDataInternal.language", FetchMode.JOIN);
crit.setFetchMode("categoriesInternal", FetchMode.JOIN);
crit.setFetchMode("categoriesInternal.parentCategory", FetchMode.JOIN);
crit.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
crit.setCacheMode(CacheMode.IGNORE);
return crit.list();
Code:
Hibernate: select this_.title_pk as title1_1077_4_, this_.asset_billing_state_fk as asset2_1077_4_, this_.adult as adult1077_4_, this_.length as length1077_4_, this_.box_office as box5_1077_4_, this_.status as status1077_4_, this_.director as director1077_4_, this_.producer as producer1077_4_, this_.actors as actors1077_4_, this_.macrovision as macrovi10_1077_4_, this_.rank as rank1077_4_, this_.year as year1077_4_, tld1_.title_fk as title2_6_, tld1_.title_lang_data_pk as title1_6_, tld1_.title_lang_data_pk as title1_1078_0_, tld1_.title_fk as title2_1078_0_, tld1_.language_fk as language3_1078_0_, tld1_.title as title1078_0_, tld1_.synopsis as synopsis1078_0_, language4_.language_pk as language1_1076_1_, language4_.language as language1076_1_, language4_.abbr as abbr1076_1_, categories5_.title_fk as title2_7_, category6_.category_pk as category1_7_, category6_.category_pk as category1_1072_2_, category6_.property_fk as property2_1072_2_, category6_.parent_category as parent3_1072_2_, category6_.name as name1072_2_, category6_.list_order as list5_1072_2_, category6_.active as active1072_2_, category6_.adult as adult1072_2_, category7_.category_pk as category1_1072_3_, category7_.property_fk as property2_1072_3_, category7_.parent_category as parent3_1072_3_, category7_.name as name1072_3_, category7_.list_order as list5_1072_3_, category7_.active as active1072_3_, category7_.adult as adult1072_3_ from title this_ left outer join title_lang_data tld1_ on this_.title_pk=tld1_.title_fk left outer join languages language4_ on tld1_.language_fk=language4_.language_pk left outer join title_x_category categories5_ on this_.title_pk=categories5_.title_fk left outer join category category6_ on categories5_.category_fk=category6_.category_pk left outer join category category7_ on category6_.parent_category=category7_.category_pk where tld1_.title ilike ?
Hibernate: select studio0_.studio_pk as studio1_1080_, studio0_.country as country1080_, studio0_.state as state1080_, studio0_.name as name1080_, studio0_.main_phone_number as main5_1080_, studio0_.street as street1080_, studio0_.city as city1080_, studio0_.zip as zip1080_, studio0_.active as active1080_, studio0_.studio_abbr as studio10_1080_ from studio studio0_ where studio0_.active=1 order by studio0_.name
Hibernate: select encoder0_.encoder_pk as encoder1_1082_, encoder0_.country as country1082_, encoder0_.state as state1082_, encoder0_.name as name1082_, encoder0_.main_phone_number as main5_1082_, encoder0_.street as street1082_, encoder0_.city as city1082_, encoder0_.zip as zip1082_, encoder0_.active as active1082_ from encoder encoder0_ where encoder0_.active=1 order by encoder0_.name
Hibernate: select encoding0_.encoding_pk as encoding1_1085_0_, definition1_.definition_pk as definition1_1084_1_, encoding0_.definition_fk as definition2_1085_0_, encoding0_.encoding as encoding1085_0_, definition1_.name as name1084_1_, definition1_.abbr as abbr1084_1_ from encoding encoding0_ inner join definition definition1_ on encoding0_.definition_fk=definition1_.definition_pk order by encoding0_.encoding
Hibernate: select language0_.language_pk as language1_1076_, language0_.language as language1076_, language0_.abbr as abbr1076_ from languages language0_ where language0_.language_pk>=? order by language0_.language_pk
Hibernate: select language0_.language_pk as language1_1076_, language0_.language as language1076_, language0_.abbr as abbr1076_ from languages language0_ where language0_.language_pk>=? order by language0_.language_pk