在一对多的连接查询中主动方对象(“一”方)时,默认只有主动方对象内容,并不包含被动方对象(“多”方)的内容。因为在Hibernate中的Set集合默认使用延迟加载,因此设置Set集合的layzy属性值为true时才可以加载到集合中的内容。如:

public void testForceInnererJoin(){
         Session session = null;
          session = HibernateUtils.getCurrentSession();
          String hql = "select c from Category c  join c.products";
          Query query = session.createQuery(hql);
          List<Category> list = query.list();
          HibernateUtils.closeSession(session);
         for(Category c : list){
            System.out.println(c.toString());
            Set<Product> products = c.getProducts();
            for(Product p :products){
                System.out.println(p.toString());
            }
         }
    }
    


它生成的SQL语句如下:

Hibernate: select category0_.id as id0_, category0_.c_name as c2_0_, category0_.c_description as c3_0_ from tb_category category0_ inner join tb_product products1_ on category0_.id=products1_.category_id

Hibernate: select products0_.category_id as category5_1_, products0_.id as id1_, products0_.id as id2_0_, products0_.c_name as c2_2_0_, products0_.c_price as c3_2_0_, products0_.c_description as c4_2_0_, products0_.category_id as category5_2_0_ from tb_product products0_ where products0_.category_id=?

Hibernate: select products0_.category_id as category5_1_, products0_.id as id1_, products0_.id as id2_0_, products0_.c_name as c2_2_0_, products0_.c_price as c3_2_0_, products0_.c_description as c4_2_0_, products0_.category_id as category5_2_0_ from tb_product products0_ where products0_.category_id=?



在使用延迟加载的情况下要一次性取出当前对象所有和被关联对象的对象,需要在HQL中使用fetch子句,称为“迫切内连接”。
使用fetch的连接查询允许仅仅使用一个HQL语句即可随主动对象的初始化相关联对象或一组对象的集合,并且与Set集合是否延迟加载无关。如:

public void testForceInnererJoin1(){
         Session session = null;
          session = HibernateUtils.getCurrentSession();
          String hql = "select c from Category c  join fetch c.products";
          Query query = session.createQuery(hql);
          List<Category> list = query.list();
          HibernateUtils.closeSession(session);
         for(Category c : list){
            System.out.println(c.toString());
            Set<Product> products = c.getProducts();
            for(Product p :products){
                System.out.println(p.toString());
            }
         }
    }


它生成的SQL语句如下:

Hibernate: select category0_.id as id0_0_, products1_.id as id2_1_, category0_.c_name as c2_0_0_, category0_.c_description as c3_0_0_, products1_.c_name as c2_2_1_, products1_.c_price as c3_2_1_, products1_.c_description as c4_2_1_, products1_.category_id as category5_2_1_, products1_.category_id as category5_0__, products1_.id as id0__ from tb_category category0_ inner join tb_product products1_ on category0_.id=products1_.category_id

由此可以看出两种不同。