DAO,Spring和Hibernate

Eug*_*neP 7 java spring dao hibernate

如果出现任何问题,请纠正我.

现在,当我们使用Spring DAO作为ORM模板时,当我们使用@Transactional属性时,当在外部调用方法时,我们无法控制事务和/或会话,而不是在方法中.

延迟加载可节省资源 - 减少对数据库的查询,减少内存以保留应用程序内存中的所有集合.

因此,如果lazy = false,那么如果链接集中有10,000条记录,那么所有相关集合都将被提取,而这些集合并不是有效的.

现在,我在DAO类中有一个方法,它应该返回一个User对象.它具有表示数据库的链接表的集合.我需要通过id获取一个对象,然后查询它的集合.

当我尝试访问此DAO方法返回的链接集合时,Hibernate"未能懒惰地初始化集合"异常发生.

请解释一下,这里的解决方法是什么?

更新:好的,我来问你这个问题.DAO是一个抽象层,因此方法"getUserById(Integer id)"应该返回一个Object.

如果在某些情况下我需要User对象的这些链接集合,而在其他情况下我需要这些集合.

是否只有两种方法:1)延迟加载=假2)创建不同的方法:getUserByIdWithTheseCollections(),getUserByIdWithOtherCollections()并在这些方法中使用你的方法?

我的意思是只有两种方式而且没有更好的方法吗?

更新2:请解释一下,什么会让我明确使用SESSIONFACTORY?它在实践中看起来如何?我们创建一个DAO对象的实例,然后用会话工厂注入它,这意味着对DAO的两个后续方法调用将在同一个事务中运行?在我看来,无论如何,DAO与使用它的类分开了!

逻辑和事务封装在DAO中,对吧?

Kon*_*rus 6

您仍然可以在事务中获取链接集合,以便在您仍在事务中时加载它:

User user = sessionFactory.getCurrentSession().get(User.class, userId);
user.getLinkedCollection().size();
return user;
Run Code Online (Sandbox Code Playgroud)

正如BalusC指出的那样,你可以用Hibernate.initialize()而不是size().那更清洁了.

然后当您返回这样的实体时,惰性字段已经初始化.

回复你的PS - 使用服务级别(而不是DAO)级别的交易是否可行?似乎是,因为在单独的事务中进行每个DAO调用似乎是浪费(并且可能是不正确的).


Joh*_*ohn 5

我发现最好将@Transactional放在服务层,而不是DAO层.否则,所有DAO调用都在单独的hibernate会话中 - 所有对象相等的东西都不起作用.