迫切左外连接
2.更深层次的级联左外连接时:
String hql = "from User u LEFT OUTER JOIN FETCH u.shoppingCartSet "
+ "LEFT OUTER JOIN FETCH u.shoppingCart.book where u.id = ?";
会报could not resolve property: shoppingCart of: entities.User [from entities.User u LEFT OUTER JOIN FETCH u.shoppingCartSet sc LEFT OUTER JOIN FETCH u.shoppingCart.book where u.id = ?]
而这样写就可以解决
String hql = "from User u LEFT OUTER JOIN FETCH u.shoppingCartSet sc "
+ "LEFT OUTER JOIN FETCH sc.book where u.id = ?";
以下是另一种情况
String hql = "from ShoppingCart sc left outer join fetch sc.book left outer join fetch sc.user.name "
+ "where sc.user.id = ?"; 会报空指针异常
但把.name去掉就不会了
String hql = "from ShoppingCart sc left outer join fetch sc.book left outer join fetch sc.user "
+ "where sc.user.id = ?";
1.left outer join fetch语句要放在where前面才行
package jiansuo_jiben; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistryBuilder; import org.junit.After; import org.junit.Before; import org.junit.Test; public class TestFetch { private SessionFactory sessionFactory; private Session session; private Transaction transaction; @Before public void before(){ Configuration configuration = new Configuration().configure(); ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()) .buildServiceRegistry(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); session = sessionFactory.openSession(); transaction = session.beginTransaction(); } @After public void after(){ transaction.commit(); session.close(); sessionFactory.close(); } /**Left join Fetch是迫切左外连接 * 1,查询到的List中是Department实体对象 * 2,且每一个实体对象中的Employee对象也已被初始化 * * */ @Test public void testFetch() { String hql = "FROM Department d Left join Fetch d.set"; Query q = session.createQuery(hql); List<Department> ds = q.list(); for(Department d:ds){ System.out.println(d +":"+ d.getSet().size()); } } /** * 对于迫切左外连接 * 两种方法去重 * 且在加载department时就将其set属性初始化(这是与左外连接的区别)(相当于强制去掉懒加载) * */ @Test public void testFetch2() { // String hql = "Select distinct d FROM Department d Left join Fetch d.set"; String hql = "FROM Department d Left join Fetch d.set"; Query q = session.createQuery(hql); List<Department> ds = q.list(); ds = new ArrayList<>(new LinkedHashSet<>(ds)); for(Department d:ds){ System.out.println(d +":"+ d.getSet().size()); } } /**左外连接 * 1,返回的List中存放的是Object[],[0]中是Department[1]中是Employee * 2,用到Department中的set时还需select,根据配置文件来决定 Employee 集合的检索策略. * */ @Test public void testFetch3() { // String hql = "Select distinct d FROM Department d Left join Fetch d.set"; String hql = "FROM Department d Left join d.set"; Query q = session.createQuery(hql); List<Object[]> ds = q.list(); // ds = new ArrayList<>(new LinkedHashSet<>(ds)); for(Object[] d:ds){ System.out.println(Arrays.asList(d)); System.out.println(((Department)d[0]).getSet()); } } /** * 只用这种方式去重, * 因为上一个方法返回的List中是数组所以不能通过LinkedHashSet去重 * */ @Test public void testFetch4() { String hql = "Select distinct d FROM Department d Left join d.set"; Query q = session.createQuery(hql); List<Department> ds = q.list(); // ds = new ArrayList<>(new LinkedHashSet<>(ds)); for(Department d:ds){ System.out.println(Arrays.asList(d)); System.out.println(d.getSet()); } } }