懒惰的人会告诉你要始终
FetchType.EAGER凭直觉来使用。这些人通常不担心数据库性能,只关心使开发工作更轻松。我要说的是您应该利用它
FetchType.LAZY来提高性能。由于数据库访问通常是大多数应用程序的性能瓶颈,因此一点点帮助。
如果确实需要获取组的用户列表,只要您
getUsers()在事务会话中进行呼叫,就不会得到
LazyLoadingException所有新Hibernate用户的麻烦。
以下代码将为您提供所有组,而无需填充这些组的用户列表
//Service Class@Transactionalpublic List<Group> findAll(){ return groupDao.findAll();}以下代码将为您提供DAO级别的所有组的用户:
//DAO class@SuppressWarnings("unchecked")public List<Group> findAllWithUsers(){ Criteria criteria = getCurrentSession().createCriteria(Group.class); criteria.setFetchMode("users", FetchMode.SUBSELECT); //Other restrictions here as required. return criteria.list();}编辑1:感谢Adrian Shum的这段代码
有关不同类型的
FetchMode的更多信息,请参见此处
如果您不想只为访问集合对象而编写其他DAO方法,只要您与
Session用于获取父对象的对象相同,则可以使用该
Hibernate.initialize()方法来强制初始化子集合宾语。我不建议您
List<T>对父对象执行此操作。这将对数据库造成相当大的负担。
//Service Class@Transactionalpublic Group findWithUsers(UUID groupId){ Group group = groupDao.find(groupId); //Forces the initialization of the collection object returned by getUsers() Hibernate.initialize(group.getUsers()); return group;}我没有遇到必须使用上述代码的情况,但是它应该相对有效。有关更多信息,
Hibernate.initialize()请参见此处
我已经在服务层中完成了此操作,而不是在DAO中获取它们,因为那样的话,您只需要在服务中创建一个新方法,而不必再创建单独的DAO方法。重要的是您已将
getUsers()调用包装在事务中,因此将创建一个会话,Hibernate可以使用该会话来运行其他查询。也可以在DAO中通过向您的集合编写联接条件来完成此操作,但是我从来不必自己做。
就是说,如果您发现调用第二个方法的次数比调用第一个方法的次数多,请考虑将获取类型更改为
EAGER并让数据库为您完成工作。



