在 Struts 2 中使用 Hibernate 克服延迟初始化和性能问题

问题描述 投票:0回答:2

在 Hibernate 中,

@ManyToOne
关系几乎不会导致任何问题,因为默认获取类型是
EAGER

然而,我们在

@OnetoMany
最后遇到了关键问题。当我们尝试获取集合时,

LazyInitializationException: could not initialize proxy 

被抛出,因为对于

one-to-many
,默认的获取类型是 LAZY

在这种情况下,我们可以设置:

  • @LazyCollection(LazyCollectionOption.FALSE)
    ,虽然解决了问题,但是当有一堆记录时,它会显着影响性能。

  • fetch
    模式:左连接但会抛出

    org.hibernate.HibernateException: cannot simultaneously fetch multiple bags
    

据我所知,Hibernate 建议了几种机制来克服这个问题:

  • 选项1:

    • 指定

      @IndexColumn
      而不是制作
      LazyCollectionOption.FALSE
      。因此,确定了以下也会影响性能的行为:

    • 使用各个实体的主键创建临时表(

      @OnetoMany
      )。因此,当存在许多一对多关系时,将为每个关系创建临时表。

  • 选项2:

    • 将集合的数据类型从

      List
      更改为
      Set
      。这会导致 Struts 2 前端出现问题,因为
      Set
      是基于索引的集合,因为我们需要以迭代方式动态添加记录。

    • 为了克服这个问题,我们将利用 DTO 来捕获 UI 输入。通过在 DTO 中创建集合类型

      List
      ,在
      domain
      中创建Set,并通过汇编器,我们将进行从
      List
      Set
      (DTO → 域)所需的转换,反之亦然。

选项 2 中提到的解决方案是否可行?如果没有,请提供建议和反馈。

java performance hibernate struts2 lazy-initialization
2个回答
0
投票

根据我的经验,通常只有一两个地方需要急切初始化(例如:在“记录详细信息”视图中)。对于这种情况,除了一些需要 eager 的地方之外,总是存在惰性的情况,有一个名为 “Fetch profile” 的 Hibernate 功能。这是一个相对较新的功能,不太为人所知,但它非常强大,在这种情况下可能会有所帮助。

不幸的是,这还没有在 JPA 中,这意味着您需要在干净的 JPA 代码中添加一些专有的 Hibernate 部分,但在我看来,这是一个很低的价格。


0
投票

如果您尝试访问

一对多
属性或集合中的对象并且目前没有打开的会话,则会抛出LazyInitializationException

默认情况下,关联是为延迟初始化而设计的,这是解决性能问题的好方法,具有可以按需初始化的一对多属性。

唯一的问题是会话状态。为此,Hibernate 强加了“在视图中打开会话”模式。 您可以使用自定义拦截器手动实现它,或者使用已经通过

Struts2 的完整 Hibernate 插件实现的

在他们的

showcase

中查看此插件如何与 Struts2 jQuery Grid 插件一起使用。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.