【问题标题】:Proper use of getHibernateTemplate() in Spring MVC app?在 Spring MVC 应用程序中正确使用 getHibernateTemplate()?
【发布时间】:2011-01-03 16:30:01
【问题描述】:

我的 Spring MVC 应用程序中有一堆 Hibernate 映射对象。对于具有关系的嵌套对象,默认似乎是延迟加载。我通过在访问时在我的 JSP 中遇到很多错误来实现这一点,例如子对象列表。

所以我实现了第二种方法来获取所有子对象都已初始化的对象列表。我想知道如果这是否可行,是否有人可以给我一些反馈?

这是我的 DAO 实现中有效的代码:

public List<Address> getTripListFullyInitliazed() {

    HibernateTemplate template = getHibernateTemplate();

    List<Address> addresses = template.loadAll(Address.class);
    for (Address address : address) {
        template.initialize(address.getChildren());
    }
    return addresses;   
}

有人可以告诉我这样做是否可行,或者我是否应该改变一些东西?

【问题讨论】:

  • 如果它适合你,那就没关系
  • 哪个版本的spring?

标签: java hibernate spring initialization lazy-evaluation


【解决方案1】:

我认为更优雅的方法是使用 HQL JOIN FETCH 子句,因为它最大限度地减少了发出的 SQL 查询的数量,并使您的代码更清晰:

public List<Address> getTripListFullyInitliazed() {
    return getHibernateTemplate().find(
        "from Address a left join fetch a.children");
}

另请参阅:

【讨论】:

  • 嗯...我必须阅读一些关于它的文档,因为我不明白我应该如何使用它,例如在上面的代码中。不过谢谢你的提示。
  • @Czar:代码已更新。此查询指示 Hibernate 返回具有完全初始化的 children 集合的实体。
  • THX。当还有那些标准方法时,您是否应该真正使用 HQl?
  • @Czar:我认为将您的意图传递给 Hibernate 以生成高效的 SQL 查询非常重要。请注意,在这种特殊情况下,如果您确实需要所有带有孩子的地址,我的方法会在一个 SQL 查询中获取所有数据,而您的原始方法和 OpenSessionInViewFilter 方法会受到 N + 1 problem 的影响。
  • @Czar:是的,这是最简单的方法,尽管 Hibernate 有一些高级功能:docs.jboss.org/hibernate/core/3.6/reference/en-US/html/…
【解决方案2】:

我认为这个问题的标准解决方案是使用OpenSessionInViewFilter

Servlet 2.3 过滤器将 Hibernate Session 绑定到线程,用于整个请求处理。用于“在视图中打开会话”模式,即允许在 Web 视图中延迟加载,尽管原始事务已经完成。

此过滤器使 Hibernate Sessions 通过当前线程可用,事务管理器将自动检测到该线程。它适用于通过HibernateTransactionManagerJtaTransactionManager 进行的服务层事务以及非事务性执行(如果配置得当)。

【讨论】:

  • 绝对是最好的解决方案,在复杂查询中使用 JOIN 操作变得困难。
  • 我没有直接使用任何JOIN?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-02
  • 2018-12-30
  • 2017-08-25
  • 2020-03-30
  • 2021-05-30
  • 2023-03-16
  • 2020-03-04
相关资源
最近更新 更多