一尘不染

DAO,Spring 和Hibernate

hibernate

如果有什么问题请指正。

现在,当我们将Spring
DAO用于ORM模板时,当我们使用@Transactional属性时,从外部而不是在方法内部调用该方法时,我们将无法控制事务和/或会话。

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

因此,如果lazy = false,则在链接集中有10,000条记录的情况下,所有相关联的集合都将被提取,这并不是很有效。

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

当我尝试访问此DAO方法返回的链接集合时,会发生Hibernate“无法延迟初始化集合”异常。

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

更新 :好的,让我问你这个。DAO是抽象层,因此应该使用方法“ getUserById(Integer id)”返回一个Object。

如果在某些情况下我需要这些User对象的链接集合,而在其他情况下我需要那些集合,该怎么办?

只有两种方法:1)延迟加载= false
2)创建不同的方法:getUserByIdWithTheseCollections(),getUserByIdWithOtherCollections()以及在这些方法内部使用您的方法?

我的意思是只有2种方法,没有更好的方法吗?

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

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


阅读 299

收藏
2020-06-20

共1个答案

一尘不染

您可以在事务中获取链接的集合以加载它,而仍在事务中:

User user = sessionFactory.getCurrentSession().get(User.class, userId);
user.getLinkedCollection().size();
return user;

正如BalusC指出的那样,您可以使用Hibernate.initialize()代替size()。干净很多。

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

回复您的PS-在服务级别(而不是DAO)级别使用事务是否可行?好像是这样,因为在单独的事务中进行每个DAO调用似乎是一种浪费(并且可能是错误的)。

2020-06-20