hibernate 多表 join 查询发现还是会重新load one-to-many 子表

原来的系统性能慢,今天在做性能调优,发现有一个多表查询存在性能问题。

我的hbm.xml配置文件
[code="java"]












[/code]

查询语句:

   [code="java"] Criteria criteria = getSession().createCriteria(Shop.class, "s")
            .createAlias("s.shopHours", "h", JoinFragment.LEFT_OUTER_JOIN)
            .createAlias("s.shopRate", "r", JoinFragment.LEFT_OUTER_JOIN)
            .createAlias("s.shopConditions", "c", JoinFragment.LEFT_OUTER_JOIN)
            .add(Restrictions.eq("s.shopCity", cityName))
            .add(Restrictions.eq("s.shopActived", true))
            .add(Restrictions.eq("s.shopPublic", true))
            .addOrder(Order.asc("s.shopNum"))
            .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
    return criteria.list();[/code]

调试中的sql 日志:
[code="java"]
Hibernate: /* load wm.model.ShopRate / select shoprate0_.shop_num as shop1_36_0_, shoprate0_.taste_rating as taste2_36_0_, shoprate0_.service_rating as service3_36_0_, shoprate0_.response_rating as response4_36_0_, shoprate0_.total_rating as total5_36_0_, shoprate0_.reviews_count as reviews6_36_0_ from shop_rate shoprate0_ where shoprate0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopHours / select shophours0_.shop_num as shop2_1_, shophours0_.shop_hour_id as shop1_1_, shophours0_.shop_hour_id as shop1_23_0_, shophours0_.shop_num as shop2_23_0_, shophours0_.time_from as time3_23_0_, shophours0_.time_to as time4_23_0_ from shop_hour shophours0_ where shophours0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopConditions / select shopcondit0_.shop_num as shop2_1_, shopcondit0_.condition_id as condition1_1_, shopcondit0_.condition_id as condition1_37_0_, shopcondit0_.shop_num as shop2_37_0_, shopcondit0_.condition_mile as condition3_37_0_, shopcondit0_.condition_money as condition4_37_0_, shopcondit0_.condition_amount as condition5_37_0_, shopcondit0_.condition_response_time as condition6_37_0_ from shop_condition shopcondit0_ where shopcondit0_.shop_num=?
Hibernate: /
load wm.model.ShopRate / select shoprate0_.shop_num as shop1_36_0_, shoprate0_.taste_rating as taste2_36_0_, shoprate0_.service_rating as service3_36_0_, shoprate0_.response_rating as response4_36_0_, shoprate0_.total_rating as total5_36_0_, shoprate0_.reviews_count as reviews6_36_0_ from shop_rate shoprate0_ where shoprate0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopHours / select shophours0_.shop_num as shop2_1_, shophours0_.shop_hour_id as shop1_1_, shophours0_.shop_hour_id as shop1_23_0_, shophours0_.shop_num as shop2_23_0_, shophours0_.time_from as time3_23_0_, shophours0_.time_to as time4_23_0_ from shop_hour shophours0_ where shophours0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopConditions / select shopcondit0_.shop_num as shop2_1_, shopcondit0_.condition_id as condition1_1_, shopcondit0_.condition_id as condition1_37_0_, shopcondit0_.shop_num as shop2_37_0_, shopcondit0_.condition_mile as condition3_37_0_, shopcondit0_.condition_money as condition4_37_0_, shopcondit0_.condition_amount as condition5_37_0_, shopcondit0_.condition_response_time as condition6_37_0_ from shop_condition shopcondit0_ where shopcondit0_.shop_num=?
Hibernate: /
load wm.model.ShopRate / select shoprate0_.shop_num as shop1_36_0_, shoprate0_.taste_rating as taste2_36_0_, shoprate0_.service_rating as service3_36_0_, shoprate0_.response_rating as response4_36_0_, shoprate0_.total_rating as total5_36_0_, shoprate0_.reviews_count as reviews6_36_0_ from shop_rate shoprate0_ where shoprate0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopHours / select shophours0_.shop_num as shop2_1_, shophours0_.shop_hour_id as shop1_1_, shophours0_.shop_hour_id as shop1_23_0_, shophours0_.shop_num as shop2_23_0_, shophours0_.time_from as time3_23_0_, shophours0_.time_to as time4_23_0_ from shop_hour shophours0_ where shophours0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopConditions / select shopcondit0_.shop_num as shop2_1_, shopcondit0_.condition_id as condition1_1_, shopcondit0_.condition_id as condition1_37_0_, shopcondit0_.shop_num as shop2_37_0_, shopcondit0_.condition_mile as condition3_37_0_, shopcondit0_.condition_money as condition4_37_0_, shopcondit0_.condition_amount as condition5_37_0_, shopcondit0_.condition_response_time as condition6_37_0_ from shop_condition shopcondit0_ where shopcondit0_.shop_num=?
Hibernate: /
load wm.model.ShopRate / select shoprate0_.shop_num as shop1_36_0_, shoprate0_.taste_rating as taste2_36_0_, shoprate0_.service_rating as service3_36_0_, shoprate0_.response_rating as response4_36_0_, shoprate0_.total_rating as total5_36_0_, shoprate0_.reviews_count as reviews6_36_0_ from shop_rate shoprate0_ where shoprate0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopHours / select shophours0_.shop_num as shop2_1_, shophours0_.shop_hour_id as shop1_1_, shophours0_.shop_hour_id as shop1_23_0_, shophours0_.shop_num as shop2_23_0_, shophours0_.time_from as time3_23_0_, shophours0_.time_to as time4_23_0_ from shop_hour shophours0_ where shophours0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopConditions / select shopcondit0_.shop_num as shop2_1_, shopcondit0_.condition_id as condition1_1_, shopcondit0_.condition_id as condition1_37_0_, shopcondit0_.shop_num as shop2_37_0_, shopcondit0_.condition_mile as condition3_37_0_, shopcondit0_.condition_money as condition4_37_0_, shopcondit0_.condition_amount as condition5_37_0_, shopcondit0_.condition_response_time as condition6_37_0_ from shop_condition shopcondit0_ where shopcondit0_.shop_num=?
Hibernate: /
load wm.model.ShopRate / select shoprate0_.shop_num as shop1_36_0_, shoprate0_.taste_rating as taste2_36_0_, shoprate0_.service_rating as service3_36_0_, shoprate0_.response_rating as response4_36_0_, shoprate0_.total_rating as total5_36_0_, shoprate0_.reviews_count as reviews6_36_0_ from shop_rate shoprate0_ where shoprate0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopHours / select shophours0_.shop_num as shop2_1_, shophours0_.shop_hour_id as shop1_1_, shophours0_.shop_hour_id as shop1_23_0_, shophours0_.shop_num as shop2_23_0_, shophours0_.time_from as time3_23_0_, shophours0_.time_to as time4_23_0_ from shop_hour shophours0_ where shophours0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopConditions / select shopcondit0_.shop_num as shop2_1_, shopcondit0_.condition_id as condition1_1_, shopcondit0_.condition_id as condition1_37_0_, shopcondit0_.shop_num as shop2_37_0_, shopcondit0_.condition_mile as condition3_37_0_, shopcondit0_.condition_money as condition4_37_0_, shopcondit0_.condition_amount as condition5_37_0_, shopcondit0_.condition_response_time as condition6_37_0_ from shop_condition shopcondit0_ where shopcondit0_.shop_num=?
Hibernate: /
load wm.model.ShopRate / select shoprate0_.shop_num as shop1_36_0_, shoprate0_.taste_rating as taste2_36_0_, shoprate0_.service_rating as service3_36_0_, shoprate0_.response_rating as response4_36_0_, shoprate0_.total_rating as total5_36_0_, shoprate0_.reviews_count as reviews6_36_0_ from shop_rate shoprate0_ where shoprate0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopHours / select shophours0_.shop_num as shop2_1_, shophours0_.shop_hour_id as shop1_1_, shophours0_.shop_hour_id as shop1_23_0_, shophours0_.shop_num as shop2_23_0_, shophours0_.time_from as time3_23_0_, shophours0_.time_to as time4_23_0_ from shop_hour shophours0_ where shophours0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopConditions / select shopcondit0_.shop_num as shop2_1_, shopcondit0_.condition_id as condition1_1_, shopcondit0_.condition_id as condition1_37_0_, shopcondit0_.shop_num as shop2_37_0_, shopcondit0_.condition_mile as condition3_37_0_, shopcondit0_.condition_money as condition4_37_0_, shopcondit0_.condition_amount as condition5_37_0_, shopcondit0_.condition_response_time as condition6_37_0_ from shop_condition shopcondit0_ where shopcondit0_.shop_num=?
Hibernate: /
load wm.model.ShopRate / select shoprate0_.shop_num as shop1_36_0_, shoprate0_.taste_rating as taste2_36_0_, shoprate0_.service_rating as service3_36_0_, shoprate0_.response_rating as response4_36_0_, shoprate0_.total_rating as total5_36_0_, shoprate0_.reviews_count as reviews6_36_0_ from shop_rate shoprate0_ where shoprate0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopHours / select shophours0_.shop_num as shop2_1_, shophours0_.shop_hour_id as shop1_1_, shophours0_.shop_hour_id as shop1_23_0_, shophours0_.shop_num as shop2_23_0_, shophours0_.time_from as time3_23_0_, shophours0_.time_to as time4_23_0_ from shop_hour shophours0_ where shophours0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopConditions / select shopcondit0_.shop_num as shop2_1_, shopcondit0_.condition_id as condition1_1_, shopcondit0_.condition_id as condition1_37_0_, shopcondit0_.shop_num as shop2_37_0_, shopcondit0_.condition_mile as condition3_37_0_, shopcondit0_.condition_money as condition4_37_0_, shopcondit0_.condition_amount as condition5_37_0_, shopcondit0_.condition_response_time as condition6_37_0_ from shop_condition shopcondit0_ where shopcondit0_.shop_num=?
Hibernate: /
load wm.model.ShopRate / select shoprate0_.shop_num as shop1_36_0_, shoprate0_.taste_rating as taste2_36_0_, shoprate0_.service_rating as service3_36_0_, shoprate0_.response_rating as response4_36_0_, shoprate0_.total_rating as total5_36_0_, shoprate0_.reviews_count as reviews6_36_0_ from shop_rate shoprate0_ where shoprate0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopHours / select shophours0_.shop_num as shop2_1_, shophours0_.shop_hour_id as shop1_1_, shophours0_.shop_hour_id as shop1_23_0_, shophours0_.shop_num as shop2_23_0_, shophours0_.time_from as time3_23_0_, shophours0_.time_to as time4_23_0_ from shop_hour shophours0_ where shophours0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopConditions / select shopcondit0_.shop_num as shop2_1_, shopcondit0_.condition_id as condition1_1_, shopcondit0_.condition_id as condition1_37_0_, shopcondit0_.shop_num as shop2_37_0_, shopcondit0_.condition_mile as condition3_37_0_, shopcondit0_.condition_money as condition4_37_0_, shopcondit0_.condition_amount as condition5_37_0_, shopcondit0_.condition_response_time as condition6_37_0_ from shop_condition shopcondit0_ where shopcondit0_.shop_num=?
Hibernate: /
load wm.model.ShopRate / select shoprate0_.shop_num as shop1_36_0_, shoprate0_.taste_rating as taste2_36_0_, shoprate0_.service_rating as service3_36_0_, shoprate0_.response_rating as response4_36_0_, shoprate0_.total_rating as total5_36_0_, shoprate0_.reviews_count as reviews6_36_0_ from shop_rate shoprate0_ where shoprate0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopHours / select shophours0_.shop_num as shop2_1_, shophours0_.shop_hour_id as shop1_1_, shophours0_.shop_hour_id as shop1_23_0_, shophours0_.shop_num as shop2_23_0_, shophours0_.time_from as time3_23_0_, shophours0_.time_to as time4_23_0_ from shop_hour shophours0_ where shophours0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopConditions / select shopcondit0_.shop_num as shop2_1_, shopcondit0_.condition_id as condition1_1_, shopcondit0_.condition_id as condition1_37_0_, shopcondit0_.shop_num as shop2_37_0_, shopcondit0_.condition_mile as condition3_37_0_, shopcondit0_.condition_money as condition4_37_0_, shopcondit0_.condition_amount as condition5_37_0_, shopcondit0_.condition_response_time as condition6_37_0_ from shop_condition shopcondit0_ where shopcondit0_.shop_num=?
Hibernate: /
load wm.model.ShopRate / select shoprate0_.shop_num as shop1_36_0_, shoprate0_.taste_rating as taste2_36_0_, shoprate0_.service_rating as service3_36_0_, shoprate0_.response_rating as response4_36_0_, shoprate0_.total_rating as total5_36_0_, shoprate0_.reviews_count as reviews6_36_0_ from shop_rate shoprate0_ where shoprate0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopHours / select shophours0_.shop_num as shop2_1_, shophours0_.shop_hour_id as shop1_1_, shophours0_.shop_hour_id as shop1_23_0_, shophours0_.shop_num as shop2_23_0_, shophours0_.time_from as time3_23_0_, shophours0_.time_to as time4_23_0_ from shop_hour shophours0_ where shophours0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopConditions / select shopcondit0_.shop_num as shop2_1_, shopcondit0_.condition_id as condition1_1_, shopcondit0_.condition_id as condition1_37_0_, shopcondit0_.shop_num as shop2_37_0_, shopcondit0_.condition_mile as condition3_37_0_, shopcondit0_.condition_money as condition4_37_0_, shopcondit0_.condition_amount as condition5_37_0_, shopcondit0_.condition_response_time as condition6_37_0_ from shop_condition shopcondit0_ where shopcondit0_.shop_num=?
Hibernate: /
load wm.model.ShopRate / select shoprate0_.shop_num as shop1_36_0_, shoprate0_.taste_rating as taste2_36_0_, shoprate0_.service_rating as service3_36_0_, shoprate0_.response_rating as response4_36_0_, shoprate0_.total_rating as total5_36_0_, shoprate0_.reviews_count as reviews6_36_0_ from shop_rate shoprate0_ where shoprate0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopHours / select shophours0_.shop_num as shop2_1_, shophours0_.shop_hour_id as shop1_1_, shophours0_.shop_hour_id as shop1_23_0_, shophours0_.shop_num as shop2_23_0_, shophours0_.time_from as time3_23_0_, shophours0_.time_to as time4_23_0_ from shop_hour shophours0_ where shophours0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopConditions / select shopcondit0_.shop_num as shop2_1_, shopcondit0_.condition_id as condition1_1_, shopcondit0_.condition_id as condition1_37_0_, shopcondit0_.shop_num as shop2_37_0_, shopcondit0_.condition_mile as condition3_37_0_, shopcondit0_.condition_money as condition4_37_0_, shopcondit0_.condition_amount as condition5_37_0_, shopcondit0_.condition_response_time as condition6_37_0_ from shop_condition shopcondit0_ where shopcondit0_.shop_num=?
Hibernate: /
load wm.model.ShopRate / select shoprate0_.shop_num as shop1_36_0_, shoprate0_.taste_rating as taste2_36_0_, shoprate0_.service_rating as service3_36_0_, shoprate0_.response_rating as response4_36_0_, shoprate0_.total_rating as total5_36_0_, shoprate0_.reviews_count as reviews6_36_0_ from shop_rate shoprate0_ where shoprate0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopHours / select shophours0_.shop_num as shop2_1_, shophours0_.shop_hour_id as shop1_1_, shophours0_.shop_hour_id as shop1_23_0_, shophours0_.shop_num as shop2_23_0_, shophours0_.time_from as time3_23_0_, shophours0_.time_to as time4_23_0_ from shop_hour shophours0_ where shophours0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopConditions / select shopcondit0_.shop_num as shop2_1_, shopcondit0_.condition_id as condition1_1_, shopcondit0_.condition_id as condition1_37_0_, shopcondit0_.shop_num as shop2_37_0_, shopcondit0_.condition_mile as condition3_37_0_, shopcondit0_.condition_money as condition4_37_0_, shopcondit0_.condition_amount as condition5_37_0_, shopcondit0_.condition_response_time as condition6_37_0_ from shop_condition shopcondit0_ where shopcondit0_.shop_num=?
Hibernate: /
load wm.model.ShopRate / select shoprate0_.shop_num as shop1_36_0_, shoprate0_.taste_rating as taste2_36_0_, shoprate0_.service_rating as service3_36_0_, shoprate0_.response_rating as response4_36_0_, shoprate0_.total_rating as total5_36_0_, shoprate0_.reviews_count as reviews6_36_0_ from shop_rate shoprate0_ where shoprate0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopHours / select shophours0_.shop_num as shop2_1_, shophours0_.shop_hour_id as shop1_1_, shophours0_.shop_hour_id as shop1_23_0_, shophours0_.shop_num as shop2_23_0_, shophours0_.time_from as time3_23_0_, shophours0_.time_to as time4_23_0_ from shop_hour shophours0_ where shophours0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopConditions / select shopcondit0_.shop_num as shop2_1_, shopcondit0_.condition_id as condition1_1_, shopcondit0_.condition_id as condition1_37_0_, shopcondit0_.shop_num as shop2_37_0_, shopcondit0_.condition_mile as condition3_37_0_, shopcondit0_.condition_money as condition4_37_0_, shopcondit0_.condition_amount as condition5_37_0_, shopcondit0_.condition_response_time as condition6_37_0_ from shop_condition shopcondit0_ where shopcondit0_.shop_num=?
Hibernate: /
load wm.model.ShopRate / select shoprate0_.shop_num as shop1_36_0_, shoprate0_.taste_rating as taste2_36_0_, shoprate0_.service_rating as service3_36_0_, shoprate0_.response_rating as response4_36_0_, shoprate0_.total_rating as total5_36_0_, shoprate0_.reviews_count as reviews6_36_0_ from shop_rate shoprate0_ where shoprate0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopHours / select shophours0_.shop_num as shop2_1_, shophours0_.shop_hour_id as shop1_1_, shophours0_.shop_hour_id as shop1_23_0_, shophours0_.shop_num as shop2_23_0_, shophours0_.time_from as time3_23_0_, shophours0_.time_to as time4_23_0_ from shop_hour shophours0_ where shophours0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopConditions / select shopcondit0_.shop_num as shop2_1_, shopcondit0_.condition_id as condition1_1_, shopcondit0_.condition_id as condition1_37_0_, shopcondit0_.shop_num as shop2_37_0_, shopcondit0_.condition_mile as condition3_37_0_, shopcondit0_.condition_money as condition4_37_0_, shopcondit0_.condition_amount as condition5_37_0_, shopcondit0_.condition_response_time as condition6_37_0_ from shop_condition shopcondit0_ where shopcondit0_.shop_num=?
Hibernate: /
load wm.model.ShopRate / select shoprate0_.shop_num as shop1_36_0_, shoprate0_.taste_rating as taste2_36_0_, shoprate0_.service_rating as service3_36_0_, shoprate0_.response_rating as response4_36_0_, shoprate0_.total_rating as total5_36_0_, shoprate0_.reviews_count as reviews6_36_0_ from shop_rate shoprate0_ where shoprate0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopHours / select shophours0_.shop_num as shop2_1_, shophours0_.shop_hour_id as shop1_1_, shophours0_.shop_hour_id as shop1_23_0_, shophours0_.shop_num as shop2_23_0_, shophours0_.time_from as time3_23_0_, shophours0_.time_to as time4_23_0_ from shop_hour shophours0_ where shophours0_.shop_num=?
Hibernate: /
load one-to-many wm.model.Shop.shopConditions */ select shopcondit0_.shop_num as shop2_1_, shopcondit0_.condition_id as condition1_1_, shopcondit0_.condition_id as condition1_37_0_, shopcondit0_.shop_num as shop2_37_0_, shopcondit0_.condition_mile as condition3_37_0_, shopcondit0_.condition_money as condition4_37_0_, shopcondit0_.condition_amount as condition5_37_0_, shopcondit0_.condition_response_time as condition6_37_0_ from shop_condition shopcondit0_ where shopcondit0_.shop_num=?[/code]

从上述日志,我发现hibernate join查询后,还是重新做了select查询,调试了半天,没有什么眉目,希望有高人指导,谢谢!

补充:
两个与查询有关的配置参数
hibernate.max_fetch_depth 3
hibernate.default_batch_fetch_size 8
[b]问题补充:[/b]
fetch 方式 select,subselect,join均试过,打印出来的sql语句相同,均存在n+1查询问题。

另外,一对多是可空的,即多的一端可以有一个或多个,也可以不存在。

另外,在创建critia时,已经设定了以做左连接方式join查询(JoinFragment.LEFT_OUTER_JOIN),应该来说会覆盖hbm配置文件中的设定。

[b]问题补充:[/b]
现在的我的使用场景中,必须设置lazy=false,否则代码调整量比较大的。
[b]问题补充:[/b]
我的问题主要有一个疑惑:从上述SQL语句中我们发现,hibernate确实已经使用了join方式查询,为什么还需要重新select呢?

[quote]问题补充:
我的问题主要有一个疑惑:从上述SQL语句中我们发现,hibernate确实已经使用了join方式查询,为什么还需要重新select呢?[/quote]

这个已经很说明问题了。 就是说hql里用的join得到对象用的行映射,并不是关联映射。
就是说当你访问shop.getShopConditions()时,是用shop对象的关系去取 shopCondition
而不是你的hql里行关联的ShopConditions

看样子你是触发了n+1次查询,
给几个建议。
1.批量抓取,加上batch-size="15",这种应该可以大幅缩减你的sql语句的数量,只是batch-size的值不好确定
2.用子查询,把fetch="select"改成fetch="subselect"
3. 贪婪加载,虽然你用了lazy="false",但还得加一条,把fetch="select"改成fetch="join"。
你可以试试,看看效果,不过我还是推荐2,3条

已经定义了关系,为什么还要用join取关系另一端的值.
貌似这个是用sql习惯来理解hibernate了。
你已经声明了outer join = true……

也就是说shopConditions shopHour直接用
shop.getShopConditions,shop.getShopHours访问。

当然,如果是view里用到这个数据,那就要OpenSessionInView了。

在hbm配置上,我们还是要配置成延迟加载的,当我们需要立即加载时,我们在程序中根据需要通过编码实现迫切连接查询, 一次性加载所有的数据

List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "Fritz%") )
[color=red] .setFetchMode("mate", FetchMode.EAGER)
.setFetchMode("kittens", FetchMode.EAGER)[/color]
.list();
再如
String hql = “select emp from Employee emp inner join [color=red]fetch[/color] emp.depart dept”
List list = getSession().createQuery(hql).list();

部门
[code="java"]








//除了outer-join="true"以外和楼主都是一样的






[/code]
员工
[code="java"]




SEQ_EMP


















[/code]

Dao

[code="java"]public List<Department> searchCriteria()
{

    Criteria c = this.getSession(true).createCriteria(Department.class,"d");
    c.createAlias("d.emps", "emps",JoinFragment.LEFT_OUTER_JOIN);
    c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);  
    return c.list();
}[/code]

test

[code="java"]public class Test extends AbstractDependencyInjectionSpringContextTests {
protected String[] getConfigLocations() {
return new String[] { "classpath:applicationContext.xml" };
}

private IDeptDao deptDAO;
    public IDeptDao getDeptDAO() {
    return deptDAO;
}

public void setDeptDAO(IDeptDao deptDAO) {
    this.deptDAO = deptDAO;
}

    public void testLeftJoin() throws Exception {
          List<Department> list = deptDAO.searchCriteria();
        for(Department d:list)
        {
            System.out.println(d.getDeptName()+" 部门:");

            for(Employee e : d.getEmps())
            {

                System.out.println(e.getEmpName());
            }
        }
}

}[/code]
执行结果 : 只有一条sql
Hibernate: select this_.DEPTNO as DEPTNO0_1_, this_.DNAME as DNAME0_1_, emps1_.DEPTNO as DEPTNO3_, emps1_.EMPNO as EMPNO3_, emps1_.EMPNO as EMPNO1_0_, emps1_.DEPTNO as DEPTNO1_0_, emps1_.ENAME as ENAME1_0_, emps1_.JOB as JOB1_0_, emps1_.HIREDATE as HIREDATE1_0_, emps1_.SAL as SAL1_0_ from EXAMPLE.DEPT this_ left outer join EXAMPLE.EMP emps1_ on this_.DEPTNO=emps1_.DEPTNO
销售部门 部门:
小乔
魏延
貂蝉
张飞
研发部门test1 部门:
赵云
貂蝉3
关公

[quote]另外,在创建critia时,已经设定了以做左连接方式join查询(JoinFragment.LEFT_OUTER_JOIN),应该来说会覆盖hbm配置文件中的设定。 [/quote]

应该……
最好自己测试下,hibernate没做这方面的覆盖。

结论是没必要用left join
只用如下代码试试。
[code="java"]
Criteria criteria = getSession().createCriteria(Shop.class, "s")

              .add(Restrictions.eq("s.shopCity", cityName))  
            .add(Restrictions.eq("s.shopActived", true))  
            .add(Restrictions.eq("s.shopPublic", true))  
            .addOrder(Order.asc("s.shopNum"))  
            .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);  
    return criteria.list();  [/code]