如有不妥请指正
现在当我们将 Spring DAO 用于 ORM 模板时,当我们使用 @Transactional 属性时, 当方法在外部而不是在方法内部调用时,我们无法控制事务和/或 session 。
延迟加载可节省资源 - 减少对数据库的查询,减少将所有已提取的集合保存在应用程序内存中的内存。
因此,如果 lazy=false,则获取所有内容,所有关联的集合,如果链接集中有 10,000 条记录,那是无效的。
现在,我在 DAO 类中有一个方法应该返回一个 User 对象。 它具有代表数据库链接表的集合。 我需要通过 id 获取一个对象,然后查询它的集合。
当我尝试访问此 DAO 方法返回的链接集合时,Hibernate 发生“无法延迟初始化集合”异常。
请解释一下,这里有什么解决方法?
更新:好的,让我问你这个。 DAO 是一个抽象层,因此“getUserById(Integer id)”方法应该返回一个对象。
如果在某些情况下我需要 User 对象的这些链接集合,而在其他情况下我需要这些集合怎么办?
是否只有两种方式: 1) 延迟加载 = false 2) 创建不同的方法:getUserByIdWithTheseCollections()、getUserByIdWithOtherCollections() 以及在这些方法中使用您的方法?
我的意思是只有两种方法,没有更好的方法吗?
更新 2:请解释一下,什么可以明确使用 SESSIONFACTORY? 它在实践中看起来如何?我们创建一个 DAO 对象的实例, 然后用 session 工厂注入(inject)它,这意味着两个结果 对 DAO 的方法调用将在同一事务中运行? 在我看来,无论如何,DAO 与使用它的类是分离的!
逻辑和交易被封装在 DAO 中,对吧?
最佳答案
您可以在事务中获取链接集合以在您仍在事务中时加载它:
User user = sessionFactory.getCurrentSession().get(User.class, userId);
user.getLinkedCollection().size();
return user;
正如 BalusC 所指出的,您可以使用 Hibernate.initialize()
而不是 size()
。这样就干净多了。
那么当你返回这样一个实体时,惰性字段已经被初始化了。
回复您的 PS - 在服务级别(而不是 DAO)级别使用事务是否可行?似乎是这样,因为在单独的事务中进行每个 DAO 调用似乎是一种浪费(而且可能是不正确的)。
关于java - DAO、Spring 和 Hibernate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2447003/