问题描述
情景:博客文章类(blog),评论类(comment),评论人类(user)层级关系为: blog.getComments().get(0).getUser().getName();blog -> comment -> user在Hibernate中,我获取到blog,然后返回,那么再用blog获取comment时,就会报sesion close了,这也是OpenSessionInView的存在价值,那么请问:我是否能通过Hibernate指定要获取到的层次呢?比如,如果指定为1,那么漫游到comment不会报错,漫游到user才会报错,如果指定到2,那么漫游到user也不会报错了。
解决方案
只能通过Hibernate获取漫游的路径。比如blog 下面有categorys和comment两个list,Hibernate不会帮你load他们出来,假设你有10个blog,设定层级(假设Hibernate能设置),那你执行的sql的顺序是:先用一个sql获得10个blog,然后为每个blog各发送2条SQL得到categorys和comment。哪么你一共要发送20条SQL,仅仅是为了这个10个blog。所以Hibernate不提供这样的功能是合理的。但也不是没有办法,设置fetch的方式为join,这个设置是可以在程序运行的时候根据需要动态设置它。通过Criteria或者DetachedCriteria可以动态设置FetchMode的示例:String[] associatePaths = new String[]{"comment","comment.user"};Criteria criteria = detachedCriteria.getExecutableCriteria(session); for (int i = 0; i < associatePaths.length; i++) { criteria.setFetchMode(associatePaths[i], FetchMode.JOIN); }criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);//设置返回的是实体对象,否则返回的数组List result = criteria.list();//返回的结果则初始化了comment和comment下面的user