0

我有一个使用 Hibernate 的 Spring MVC (3.1) Web 应用程序,它一切正常 - 今天,我试图将配置完全移动到基于注释的配置(仅使用 xml 代码配置中 Spring 尚不支持的安全性内容)。

经过一些调整后,我让应用程序开始时没有错误并且主页正确加载 - 但是我看到 Hibernate 会话的一些不同行为 - 即,在加载实际触及 Hibernate 实体的页面时出现以下错误:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.tmm.web.domain.Profile.connections, no session or session was closed

这发生在以下场景中:

  1. 一个请求命中我@Controller并加载用户Profile对象
  2. 在同一个方法调用中(所以我们在这里不是在谈论分离的实体等)它试图调用profile.getConnections()
  3. Profile.connections 实际上并没有明确声明一个 fetchtype,所以应该默认为急切加载(我的理解是?),但无论哪种方式,getConnections()调用都是在加载之后直接调用的profile- 所以即使它被延迟加载也会想到,它可以很容易地返回数据库并按需加载连接。

    //@Controller 代码账户viewedUser = accountService.loadAccountByUserName(userName); model.put("viewedUserConnections",viewedUser.getUserProfile().getConnections());

    //配置文件实体@OneToMany(mappedBy = "user", cascade = CascadeType.ALL) private List connections = new ArrayList();

现在,我知道延迟加载等,所以这不是一个问题——就像我提到所有 Hibernate 的东西都正常工作一样——所以我的问题是,什么 Spring 配置可能会影响这种行为?

我可以发布我之前和之后的 xml vs annotation 配置,但我希望有人能指出我在切换时可能错过的一些配置的方向。

4

1 回答 1

2

您的假设主要是错误的:

在同一个方法调用中(所以我们在这里不是在谈论分离的实体等)

该方法是控制器的方法。在典型的 Spring 应用程序中,控制器不是事务性的,但服务是。因此,除非您配置了“在视图中打开会话”过滤器或拦截器,否则会话在事务服务方法返回时关闭,因此控制器始终使用分离的实体

Profile.connections 实际上并没有明确声明 fetchtype,因此应该默认为急切加载

没有。默认情况下,XxxToMany 关联是惰性的。

如果相同的代码在转换之前工作,我的猜测是您在视图过滤器或拦截器中有一个打开的会话,并且您在迁移到注释时忘记了它。

于 2013-05-19T18:13:11.167 回答