【问题标题】:Getting .size() of extra lazy collection out of transaction从事务中获取额外的惰性集合的 .size()
【发布时间】:2018-05-13 12:56:05
【问题描述】:

我有一个带有lazy="extra" 属性的一对多集合。

Class Foo {
   List<Bar> barList;
}

我有一个带有 lazy="false" 初始化的类,其中包含提到的类集合。

Class FooContainer {
   List<Foo> fooList;
}

我得到了带有服务的 FooContainer 实体,所以我需要在事务之外使用.size()

FooContainer fc = serviceImpl.getFCById(fooContainerId);

这样 fc.getFooList() 就被初始化了。然后我只需要得到barList 的大小。我不需要获取整个集合。

for(Foo currentItem: fc.getFooList()) {
   int barSize = currentItem.getBarList().size();
}

这是出现 LazyInitializationException 的时候。 我尝试调用此方法。

@Transactional
Class AnotherServiceImpl {
   int getBarListSize(Foo foo){ 
      return foo.getBarList().size();
   }
}

但它不起作用,因为没有会话。 我可以在AnotherServiceImpl 中执行getHibernateTemplate().getCurrentSession.initialize(foo.getBarList()),这会起作用,但我可能会获取所有项目,这是不可接受的。

有没有办法在不获取的情况下获取集合大小?

【问题讨论】:

  • 我怀疑这是实体是否被管理的问题。您应该添加用于创建 FooContainer 和 getBarListSize 调用方法的 Transaction-Propagation。
  • @aschoerk ServiceImplAnotherServiceImpl 在此处具有默认传播。我得到FooContainer fc 并调用.size() 的方法是相同的方法,而不是@Transactional

标签: java hibernate spring-transactions


【解决方案1】:

连同评论Method where I get FooContainer fc and call .size() is the same method and it is not @Transactional:

由于提交的事务,当返回 FooContainer 时,实体变得不受管理,因此无法解析“额外”惰性集合。如果调用方法也是事务性的,它也可以工作。

我看到你有以下选项,你可以:

  1. 使用默认传播使调用方法也具有事务性
  2. 或将 foo 合并到在 getBarListSize 中有效的休眠会话中以使其再次被管理。
  3. 或将 Foo 中的 barList 也设为 Lazy(false),然后在加载 FooContainer 期间获取所有内容。 (但这似乎不能接受)
  4. 或使用 group by 语句获取大小。

【讨论】:

    猜你喜欢
    • 2017-11-25
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 2018-10-25
    • 2018-01-22
    • 2017-02-05
    • 1970-01-01
    相关资源
    最近更新 更多